Subject: anonymous unions (C11)

From: Peter Eisentraut <[email-masked]>
Date: Tue, 23 Sep 2025 11:38:22 +0200

Here is another patch set to sprinkle some C11 features around the
code.  My aim is to make a little bit of use of several C11 features
as examples and encouragement for future code, and to test compilers
(although we're not yet at the point where this should really stress
any compiler).

Here, I'm proposing to make some use of anonymous unions, which are a
nice notational simplification if you nest unions inside structs,
which is pretty common in PostgreSQL code.

Often times, you have something like

struct important_thing
{
    int a;
    int b;
    union
    {
        int foo;
        int bar;
    } u;
}

(in PostgreSQL source code, often "u" is used, sometimes "d"), and
then you have to address foo as varname.u.foo, which often looks
cryptic (especially if there is more nesting).  With anonymous unions,
you can declare this as

struct important_thing
{
    int a;
    int b;
    union
    {
        int foo;
        int bar;
    };
}

and write varname.foo, which often seems clearer.

(C++ also allows this, so this will preserve C++ compatibility of the
headers.)

That said, I did go overboard here and converted all the struct/union
combinations I could find, but I'm not necessarily proposing to apply
all of them.  I'm proposing patches 0001 through 0004, which are
relatively simple or in areas that have already changed a few times
recently (so backpatching would not be trivial anyway), and/or they
are somewhat close to my heart because they originally motivated this
work a long time ago.  But if someone finds among the other patches
one that they particularly like, we could add that one as well.

From 1280b29fa4d73e2bede285ed793a041f1c09b59e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 01/23] C11 anonymous unions [pg_locale_t]

---
 src/backend/utils/adt/pg_locale_builtin.c | 20 +++----
 src/backend/utils/adt/pg_locale_icu.c     | 18 +++---
 src/backend/utils/adt/pg_locale_libc.c    | 70 +++++++++++------------
 src/include/utils/pg_locale.h             |  2 +-
 4 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/src/backend/utils/adt/pg_locale_builtin.c b/src/backend/utils/adt/pg_locale_builtin.c
index 0c9fbdb40f2..526ab3c6711 100644
--- a/src/backend/utils/adt/pg_locale_builtin.c
+++ b/src/backend/utils/adt/pg_locale_builtin.c
@@ -72,7 +72,7 @@ strlower_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
 				 pg_locale_t locale)
 {
 	return unicode_strlower(dest, destsize, src, srclen,
-							locale->info.builtin.casemap_full);
+							locale->builtin.casemap_full);
 }
 
 static size_t
@@ -83,13 +83,13 @@ strtitle_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
 		.str = src,
 		.len = srclen,
 		.offset = 0,
-		.posix = !locale->info.builtin.casemap_full,
+		.posix = !locale->builtin.casemap_full,
 		.init = false,
 		.prev_alnum = false,
 	};
 
 	return unicode_strtitle(dest, destsize, src, srclen,
-							locale->info.builtin.casemap_full,
+							locale->builtin.casemap_full,
 							initcap_wbnext, &wbstate);
 }
 
@@ -98,7 +98,7 @@ strupper_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
 				 pg_locale_t locale)
 {
 	return unicode_strupper(dest, destsize, src, srclen,
-							locale->info.builtin.casemap_full);
+							locale->builtin.casemap_full);
 }
 
 static size_t
@@ -106,13 +106,13 @@ strfold_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
 				pg_locale_t locale)
 {
 	return unicode_strfold(dest, destsize, src, srclen,
-						   locale->info.builtin.casemap_full);
+						   locale->builtin.casemap_full);
 }
 
 static bool
 wc_isdigit_builtin(pg_wchar wc, pg_locale_t locale)
 {
-	return pg_u_isdigit(wc, !locale->info.builtin.casemap_full);
+	return pg_u_isdigit(wc, !locale->builtin.casemap_full);
 }
 
 static bool
@@ -124,7 +124,7 @@ wc_isalpha_builtin(pg_wchar wc, pg_locale_t locale)
 static bool
 wc_isalnum_builtin(pg_wchar wc, pg_locale_t locale)
 {
-	return pg_u_isalnum(wc, !locale->info.builtin.casemap_full);
+	return pg_u_isalnum(wc, !locale->builtin.casemap_full);
 }
 
 static bool
@@ -154,7 +154,7 @@ wc_isprint_builtin(pg_wchar wc, pg_locale_t locale)
 static bool
 wc_ispunct_builtin(pg_wchar wc, pg_locale_t locale)
 {
-	return pg_u_ispunct(wc, !locale->info.builtin.casemap_full);
+	return pg_u_ispunct(wc, !locale->builtin.casemap_full);
 }
 
 static bool
@@ -238,8 +238,8 @@ create_pg_locale_builtin(Oid collid, MemoryContext context)
 
 	result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
 
-	result->info.builtin.locale = MemoryContextStrdup(context, locstr);
-	result->info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
+	result->builtin.locale = MemoryContextStrdup(context, locstr);
+	result->builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
 	result->deterministic = true;
 	result->collate_is_c = true;
 	result->ctype_is_c = (strcmp(locstr, "C") == 0);
diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c
index 96741e08269..9f0b4eead73 100644
--- a/src/backend/utils/adt/pg_locale_icu.c
+++ b/src/backend/utils/adt/pg_locale_icu.c
@@ -290,8 +290,8 @@ create_pg_locale_icu(Oid collid, MemoryContext context)
 	collator = make_icu_collator(iculocstr, icurules);
 
 	result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
-	result->info.icu.locale = MemoryContextStrdup(context, iculocstr);
-	result->info.icu.ucol = collator;
+	result->icu.locale = MemoryContextStrdup(context, iculocstr);
+	result->icu.ucol = collator;
 	result->deterministic = deterministic;
 	result->collate_is_c = false;
 	result->ctype_is_c = false;
@@ -571,7 +571,7 @@ strncoll_icu_utf8(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2
 	Assert(GetDatabaseEncoding() == PG_UTF8);
 
 	status = U_ZERO_ERROR;
-	result = ucol_strcollUTF8(locale->info.icu.ucol,
+	result = ucol_strcollUTF8(locale->icu.ucol,
 							  arg1, len1,
 							  arg2, len2,
 							  &status);
@@ -608,7 +608,7 @@ strnxfrm_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
 
 	ulen = uchar_convert(icu_converter, uchar, ulen + 1, src, srclen);
 
-	result_bsize = ucol_getSortKey(locale->info.icu.ucol,
+	result_bsize = ucol_getSortKey(locale->icu.ucol,
 								   uchar, ulen,
 								   (uint8_t *) dest, destsize);
 
@@ -644,7 +644,7 @@ strnxfrm_prefix_icu_utf8(char *dest, size_t destsize,
 	uiter_setUTF8(&iter, src, srclen);
 	state[0] = state[1] = 0;	/* won't need that again */
 	status = U_ZERO_ERROR;
-	result = ucol_nextSortKeyPart(locale->info.icu.ucol,
+	result = ucol_nextSortKeyPart(locale->icu.ucol,
 								  &iter,
 								  state,
 								  (uint8_t *) dest,
@@ -755,7 +755,7 @@ icu_convert_case(ICU_Convert_Func func, pg_locale_t mylocale,
 	*buff_dest = palloc(len_dest * sizeof(**buff_dest));
 	status = U_ZERO_ERROR;
 	len_dest = func(*buff_dest, len_dest, buff_source, len_source,
-					mylocale->info.icu.locale, &status);
+					mylocale->icu.locale, &status);
 	if (status == U_BUFFER_OVERFLOW_ERROR)
 	{
 		/* try again with adjusted length */
@@ -763,7 +763,7 @@ icu_convert_case(ICU_Convert_Func func, pg_locale_t mylocale,
 		*buff_dest = palloc(len_dest * sizeof(**buff_dest));
 		status = U_ZERO_ERROR;
 		len_dest = func(*buff_dest, len_dest, buff_source, len_source,
-						mylocale->info.icu.locale, &status);
+						mylocale->icu.locale, &status);
 	}
 	if (U_FAILURE(status))
 		ereport(ERROR,
@@ -859,7 +859,7 @@ strncoll_icu(const char *arg1, ssize_t len1,
 	ulen1 = uchar_convert(icu_converter, uchar1, ulen1 + 1, arg1, len1);
 	ulen2 = uchar_convert(icu_converter, uchar2, ulen2 + 1, arg2, len2);
 
-	result = ucol_strcoll(locale->info.icu.ucol,
+	result = ucol_strcoll(locale->icu.ucol,
 						  uchar1, ulen1,
 						  uchar2, ulen2);
 
@@ -904,7 +904,7 @@ strnxfrm_prefix_icu(char *dest, size_t destsize,
 	uiter_setString(&iter, uchar, ulen);
 	state[0] = state[1] = 0;	/* won't need that again */
 	status = U_ZERO_ERROR;
-	result_bsize = ucol_nextSortKeyPart(locale->info.icu.ucol,
+	result_bsize = ucol_nextSortKeyPart(locale->icu.ucol,
 										&iter,
 										state,
 										(uint8_t *) dest,
diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c
index 8d88b53c375..f56b5dbdd37 100644
--- a/src/backend/utils/adt/pg_locale_libc.c
+++ b/src/backend/utils/adt/pg_locale_libc.c
@@ -121,116 +121,116 @@ static size_t strupper_libc_mb(char *dest, size_t destsize,
 static bool
 wc_isdigit_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isdigit_l((unsigned char) wc, locale->info.lt);
+	return isdigit_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isalpha_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isalpha_l((unsigned char) wc, locale->info.lt);
+	return isalpha_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isalnum_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isalnum_l((unsigned char) wc, locale->info.lt);
+	return isalnum_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isupper_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isupper_l((unsigned char) wc, locale->info.lt);
+	return isupper_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_islower_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return islower_l((unsigned char) wc, locale->info.lt);
+	return islower_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isgraph_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isgraph_l((unsigned char) wc, locale->info.lt);
+	return isgraph_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isprint_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isprint_l((unsigned char) wc, locale->info.lt);
+	return isprint_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_ispunct_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return ispunct_l((unsigned char) wc, locale->info.lt);
+	return ispunct_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isspace_libc_sb(pg_wchar wc, pg_locale_t locale)
 {
-	return isspace_l((unsigned char) wc, locale->info.lt);
+	return isspace_l((unsigned char) wc, locale->lt);
 }
 
 static bool
 wc_isdigit_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswdigit_l((wint_t) wc, locale->info.lt);
+	return iswdigit_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_isalpha_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswalpha_l((wint_t) wc, locale->info.lt);
+	return iswalpha_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_isalnum_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswalnum_l((wint_t) wc, locale->info.lt);
+	return iswalnum_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_isupper_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswupper_l((wint_t) wc, locale->info.lt);
+	return iswupper_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_islower_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswlower_l((wint_t) wc, locale->info.lt);
+	return iswlower_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_isgraph_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswgraph_l((wint_t) wc, locale->info.lt);
+	return iswgraph_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_isprint_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswprint_l((wint_t) wc, locale->info.lt);
+	return iswprint_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_ispunct_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswpunct_l((wint_t) wc, locale->info.lt);
+	return iswpunct_l((wint_t) wc, locale->lt);
 }
 
 static bool
 wc_isspace_libc_mb(pg_wchar wc, pg_locale_t locale)
 {
-	return iswspace_l((wint_t) wc, locale->info.lt);
+	return iswspace_l((wint_t) wc, locale->lt);
 }
 
 static char
 char_tolower_libc(unsigned char ch, pg_locale_t locale)
 {
 	Assert(pg_database_encoding_max_length() == 1);
-	return tolower_l(ch, locale->info.lt);
+	return tolower_l(ch, locale->lt);
 }
 
 static bool
@@ -241,7 +241,7 @@ char_is_cased_libc(char ch, pg_locale_t locale)
 	if (is_multibyte && IS_HIGHBIT_SET(ch))
 		return true;
 	else
-		return isalpha_l((unsigned char) ch, locale->info.lt);
+		return isalpha_l((unsigned char) ch, locale->lt);
 }
 
 static pg_wchar
@@ -253,7 +253,7 @@ toupper_libc_sb(pg_wchar wc, pg_locale_t locale)
 	if (locale->is_default && wc <= (pg_wchar) 127)
 		return pg_ascii_toupper((unsigned char) wc);
 	if (wc <= (pg_wchar) UCHAR_MAX)
-		return toupper_l((unsigned char) wc, locale->info.lt);
+		return toupper_l((unsigned char) wc, locale->lt);
 	else
 		return wc;
 }
@@ -267,7 +267,7 @@ toupper_libc_mb(pg_wchar wc, pg_locale_t locale)
 	if (locale->is_default && wc <= (pg_wchar) 127)
 		return pg_ascii_toupper((unsigned char) wc);
 	if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF)
-		return towupper_l((wint_t) wc, locale->info.lt);
+		return towupper_l((wint_t) wc, locale->lt);
 	else
 		return wc;
 }
@@ -281,7 +281,7 @@ tolower_libc_sb(pg_wchar wc, pg_locale_t locale)
 	if (locale->is_default && wc <= (pg_wchar) 127)
 		return pg_ascii_tolower((unsigned char) wc);
 	if (wc <= (pg_wchar) UCHAR_MAX)
-		return tolower_l((unsigned char) wc, locale->info.lt);
+		return tolower_l((unsigned char) wc, locale->lt);
 	else
 		return wc;
 }
@@ -295,7 +295,7 @@ tolower_libc_mb(pg_wchar wc, pg_locale_t locale)
 	if (locale->is_default && wc <= (pg_wchar) 127)
 		return pg_ascii_tolower((unsigned char) wc);
 	if (sizeof(wchar_t) >= 4 || wc <= (pg_wchar) 0xFFFF)
-		return towlower_l((wint_t) wc, locale->info.lt);
+		return towlower_l((wint_t) wc, locale->lt);
 	else
 		return wc;
 }
@@ -406,7 +406,7 @@ strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
 
 	if (srclen + 1 <= destsize)
 	{
-		locale_t	loc = locale->info.lt;
+		locale_t	loc = locale->lt;
 		char	   *p;
 
 		if (srclen + 1 > destsize)
@@ -438,7 +438,7 @@ static size_t
 strlower_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
 				 pg_locale_t locale)
 {
-	locale_t	loc = locale->info.lt;
+	locale_t	loc = locale->lt;
 	size_t		result_size;
 	wchar_t    *workspace;
 	char	   *result;
@@ -491,7 +491,7 @@ strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
 
 	if (srclen + 1 <= destsize)
 	{
-		locale_t	loc = locale->info.lt;
+		locale_t	loc = locale->lt;
 		int			wasalnum = false;
 		char	   *p;
 
@@ -532,7 +532,7 @@ static size_t
 strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
 				 pg_locale_t locale)
 {
-	locale_t	loc = locale->info.lt;
+	locale_t	loc = locale->lt;
 	int			wasalnum = false;
 	size_t		result_size;
 	wchar_t    *workspace;
@@ -592,7 +592,7 @@ strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
 
 	if (srclen + 1 <= destsize)
 	{
-		locale_t	loc = locale->info.lt;
+		locale_t	loc = locale->lt;
 		char	   *p;
 
 		memcpy(dest, src, srclen);
@@ -621,7 +621,7 @@ static size_t
 strupper_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
 				 pg_locale_t locale)
 {
-	locale_t	loc = locale->info.lt;
+	locale_t	loc = locale->lt;
 	size_t		result_size;
 	wchar_t    *workspace;
 	char	   *result;
@@ -718,7 +718,7 @@ create_pg_locale_libc(Oid collid, MemoryContext context)
 		(strcmp(collate, "POSIX") == 0);
 	result->ctype_is_c = (strcmp(ctype, "C") == 0) ||
 		(strcmp(ctype, "POSIX") == 0);
-	result->info.lt = loc;
+	result->lt = loc;
 	if (!result->collate_is_c)
 	{
 #ifdef WIN32
@@ -862,7 +862,7 @@ strncoll_libc(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2,
 		arg2n = buf2;
 	}
 
-	result = strcoll_l(arg1n, arg2n, locale->info.lt);
+	result = strcoll_l(arg1n, arg2n, locale->lt);
 
 	if (buf != sbuf)
 		pfree(buf);
@@ -887,7 +887,7 @@ strnxfrm_libc(char *dest, size_t destsize, const char *src, ssize_t srclen,
 	size_t		result;
 
 	if (srclen == -1)
-		return strxfrm_l(dest, src, destsize, locale->info.lt);
+		return strxfrm_l(dest, src, destsize, locale->lt);
 
 	if (bufsize > TEXTBUFLEN)
 		buf = palloc(bufsize);
@@ -896,7 +896,7 @@ strnxfrm_libc(char *dest, size_t destsize, const char *src, ssize_t srclen,
 	memcpy(buf, src, srclen);
 	buf[srclen] = '\0';
 
-	result = strxfrm_l(dest, buf, destsize, locale->info.lt);
+	result = strxfrm_l(dest, buf, destsize, locale->lt);
 
 	if (buf != sbuf)
 		pfree(buf);
@@ -1038,7 +1038,7 @@ strncoll_libc_win32_utf8(const char *arg1, ssize_t len1, const char *arg2,
 	((LPWSTR) a2p)[r] = 0;
 
 	errno = 0;
-	result = wcscoll_l((LPWSTR) a1p, (LPWSTR) a2p, locale->info.lt);
+	result = wcscoll_l((LPWSTR) a1p, (LPWSTR) a2p, locale->lt);
 	if (result == 2147483647)	/* _NLSCMPERROR; missing from mingw headers */
 		ereport(ERROR,
 				(errmsg("could not compare Unicode strings: %m")));
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 2b072cafb4d..7e83594fbaf 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -171,7 +171,7 @@ struct pg_locale_struct
 			UCollator  *ucol;
 		}			icu;
 #endif
-	}			info;
+	};
 };
 
 extern void init_database_collation(void);

base-commit: a48d1ef58652229521ba4b5070e19f857608b22e
-- 
2.51.0

From 316fc9ac7512c406ad8a83b3307d1ebff3966de7 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 02/23] C11 anonymous unions [reorderbuffer xact_time]

---
 contrib/test_decoding/test_decoding.c           | 12 ++++++------
 src/backend/replication/logical/proto.c         | 14 +++++++-------
 src/backend/replication/logical/reorderbuffer.c | 14 +++++++-------
 src/backend/replication/pgoutput/pgoutput.c     |  2 +-
 src/include/replication/reorderbuffer.h         |  2 +-
 5 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c
index f671a7d4b31..36e77c69e1c 100644
--- a/contrib/test_decoding/test_decoding.c
+++ b/contrib/test_decoding/test_decoding.c
@@ -340,7 +340,7 @@ pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 
 	if (data->include_timestamp)
 		appendStringInfo(ctx->out, " (at %s)",
-						 timestamptz_to_str(txn->xact_time.commit_time));
+						 timestamptz_to_str(txn->commit_time));
 
 	OutputPluginWrite(ctx, true);
 }
@@ -391,7 +391,7 @@ pg_decode_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 
 	if (data->include_timestamp)
 		appendStringInfo(ctx->out, " (at %s)",
-						 timestamptz_to_str(txn->xact_time.prepare_time));
+						 timestamptz_to_str(txn->prepare_time));
 
 	OutputPluginWrite(ctx, true);
 }
@@ -413,7 +413,7 @@ pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn
 
 	if (data->include_timestamp)
 		appendStringInfo(ctx->out, " (at %s)",
-						 timestamptz_to_str(txn->xact_time.commit_time));
+						 timestamptz_to_str(txn->commit_time));
 
 	OutputPluginWrite(ctx, true);
 }
@@ -437,7 +437,7 @@ pg_decode_rollback_prepared_txn(LogicalDecodingContext *ctx,
 
 	if (data->include_timestamp)
 		appendStringInfo(ctx->out, " (at %s)",
-						 timestamptz_to_str(txn->xact_time.commit_time));
+						 timestamptz_to_str(txn->commit_time));
 
 	OutputPluginWrite(ctx, true);
 }
@@ -874,7 +874,7 @@ pg_decode_stream_prepare(LogicalDecodingContext *ctx,
 
 	if (data->include_timestamp)
 		appendStringInfo(ctx->out, " (at %s)",
-						 timestamptz_to_str(txn->xact_time.prepare_time));
+						 timestamptz_to_str(txn->prepare_time));
 
 	OutputPluginWrite(ctx, true);
 }
@@ -903,7 +903,7 @@ pg_decode_stream_commit(LogicalDecodingContext *ctx,
 
 	if (data->include_timestamp)
 		appendStringInfo(ctx->out, " (at %s)",
-						 timestamptz_to_str(txn->xact_time.commit_time));
+						 timestamptz_to_str(txn->commit_time));
 
 	OutputPluginWrite(ctx, true);
 }
diff --git a/src/backend/replication/logical/proto.c b/src/backend/replication/logical/proto.c
index 1b3d9eb49dd..2436a263dc2 100644
--- a/src/backend/replication/logical/proto.c
+++ b/src/backend/replication/logical/proto.c
@@ -52,7 +52,7 @@ logicalrep_write_begin(StringInfo out, ReorderBufferTXN *txn)
 
 	/* fixed fields */
 	pq_sendint64(out, txn->final_lsn);
-	pq_sendint64(out, txn->xact_time.commit_time);
+	pq_sendint64(out, txn->commit_time);
 	pq_sendint32(out, txn->xid);
 }
 
@@ -88,7 +88,7 @@ logicalrep_write_commit(StringInfo out, ReorderBufferTXN *txn,
 	/* send fields */
 	pq_sendint64(out, commit_lsn);
 	pq_sendint64(out, txn->end_lsn);
-	pq_sendint64(out, txn->xact_time.commit_time);
+	pq_sendint64(out, txn->commit_time);
 }
 
 /*
@@ -120,7 +120,7 @@ logicalrep_write_begin_prepare(StringInfo out, ReorderBufferTXN *txn)
 	/* fixed fields */
 	pq_sendint64(out, txn->final_lsn);
 	pq_sendint64(out, txn->end_lsn);
-	pq_sendint64(out, txn->xact_time.prepare_time);
+	pq_sendint64(out, txn->prepare_time);
 	pq_sendint32(out, txn->xid);
 
 	/* send gid */
@@ -173,7 +173,7 @@ logicalrep_write_prepare_common(StringInfo out, LogicalRepMsgType type,
 	/* send fields */
 	pq_sendint64(out, prepare_lsn);
 	pq_sendint64(out, txn->end_lsn);
-	pq_sendint64(out, txn->xact_time.prepare_time);
+	pq_sendint64(out, txn->prepare_time);
 	pq_sendint32(out, txn->xid);
 
 	/* send gid */
@@ -253,7 +253,7 @@ logicalrep_write_commit_prepared(StringInfo out, ReorderBufferTXN *txn,
 	/* send fields */
 	pq_sendint64(out, commit_lsn);
 	pq_sendint64(out, txn->end_lsn);
-	pq_sendint64(out, txn->xact_time.commit_time);
+	pq_sendint64(out, txn->commit_time);
 	pq_sendint32(out, txn->xid);
 
 	/* send gid */
@@ -311,7 +311,7 @@ logicalrep_write_rollback_prepared(StringInfo out, ReorderBufferTXN *txn,
 	pq_sendint64(out, prepare_end_lsn);
 	pq_sendint64(out, txn->end_lsn);
 	pq_sendint64(out, prepare_time);
-	pq_sendint64(out, txn->xact_time.commit_time);
+	pq_sendint64(out, txn->commit_time);
 	pq_sendint32(out, txn->xid);
 
 	/* send gid */
@@ -1119,7 +1119,7 @@ logicalrep_write_stream_commit(StringInfo out, ReorderBufferTXN *txn,
 	/* send fields */
 	pq_sendint64(out, commit_lsn);
 	pq_sendint64(out, txn->end_lsn);
-	pq_sendint64(out, txn->xact_time.commit_time);
+	pq_sendint64(out, txn->commit_time);
 }
 
 /*
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 4736f993c37..a5e165fb123 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -2830,7 +2830,7 @@ ReorderBufferReplay(ReorderBufferTXN *txn,
 
 	txn->final_lsn = commit_lsn;
 	txn->end_lsn = end_lsn;
-	txn->xact_time.commit_time = commit_time;
+	txn->commit_time = commit_time;
 	txn->origin_id = origin_id;
 	txn->origin_lsn = origin_lsn;
 
@@ -2922,7 +2922,7 @@ ReorderBufferRememberPrepareInfo(ReorderBuffer *rb, TransactionId xid,
 	 */
 	txn->final_lsn = prepare_lsn;
 	txn->end_lsn = end_lsn;
-	txn->xact_time.prepare_time = prepare_time;
+	txn->prepare_time = prepare_time;
 	txn->origin_id = origin_id;
 	txn->origin_lsn = origin_lsn;
 
@@ -2979,7 +2979,7 @@ ReorderBufferPrepare(ReorderBuffer *rb, TransactionId xid,
 	txn->gid = pstrdup(gid);
 
 	ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn,
-						txn->xact_time.prepare_time, txn->origin_id, txn->origin_lsn);
+						txn->prepare_time, txn->origin_id, txn->origin_lsn);
 
 	/*
 	 * Send a prepare if not already done so. This might occur if we have
@@ -3018,7 +3018,7 @@ ReorderBufferFinishPrepared(ReorderBuffer *rb, TransactionId xid,
 	 * be later used for rollback.
 	 */
 	prepare_end_lsn = txn->end_lsn;
-	prepare_time = txn->xact_time.prepare_time;
+	prepare_time = txn->prepare_time;
 
 	/* add the gid in the txn */
 	txn->gid = pstrdup(gid);
@@ -3050,12 +3050,12 @@ ReorderBufferFinishPrepared(ReorderBuffer *rb, TransactionId xid,
 		 * prepared after the restart.
 		 */
 		ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn,
-							txn->xact_time.prepare_time, txn->origin_id, txn->origin_lsn);
+							txn->prepare_time, txn->origin_id, txn->origin_lsn);
 	}
 
 	txn->final_lsn = commit_lsn;
 	txn->end_lsn = end_lsn;
-	txn->xact_time.commit_time = commit_time;
+	txn->commit_time = commit_time;
 	txn->origin_id = origin_id;
 	txn->origin_lsn = origin_lsn;
 
@@ -3095,7 +3095,7 @@ ReorderBufferAbort(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn,
 	if (txn == NULL)
 		return;
 
-	txn->xact_time.abort_time = abort_time;
+	txn->abort_time = abort_time;
 
 	/* For streamed transactions notify the remote node about the abort. */
 	if (rbtxn_is_streamed(txn))
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 80540c017bd..92eb17049c3 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -1888,7 +1888,7 @@ pgoutput_stream_abort(struct LogicalDecodingContext *ctx,
 
 	OutputPluginPrepareWrite(ctx, true);
 	logicalrep_write_stream_abort(ctx->out, toptxn->xid, txn->xid, abort_lsn,
-								  txn->xact_time.abort_time, write_abort_info);
+								  txn->abort_time, write_abort_info);
 
 	OutputPluginWrite(ctx, true);
 
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index fa0745552f8..91dc7e5e448 100644
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -359,7 +359,7 @@ typedef struct ReorderBufferTXN
 		TimestampTz commit_time;
 		TimestampTz prepare_time;
 		TimestampTz abort_time;
-	}			xact_time;
+	};
 
 	/*
 	 * The base snapshot is used to decode all changes until either this
-- 
2.51.0

From 307cd025e2c9d7dfad87c3e60b03d737a657c744 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 03/23] C11 anonymous unions [pgcrypto]

---
 contrib/pgcrypto/openssl.c | 14 +++++++-------
 contrib/pgcrypto/px.h      |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index f179e80c842..276d8306588 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -98,7 +98,7 @@ free_openssl_digest(OSSLDigest *digest)
 static unsigned
 digest_result_size(PX_MD *h)
 {
-	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+	OSSLDigest *digest = (OSSLDigest *) h->ptr;
 	int			result = EVP_MD_CTX_size(digest->ctx);
 
 	if (result < 0)
@@ -110,7 +110,7 @@ digest_result_size(PX_MD *h)
 static unsigned
 digest_block_size(PX_MD *h)
 {
-	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+	OSSLDigest *digest = (OSSLDigest *) h->ptr;
 	int			result = EVP_MD_CTX_block_size(digest->ctx);
 
 	if (result < 0)
@@ -122,7 +122,7 @@ digest_block_size(PX_MD *h)
 static void
 digest_reset(PX_MD *h)
 {
-	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+	OSSLDigest *digest = (OSSLDigest *) h->ptr;
 
 	if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))
 		elog(ERROR, "EVP_DigestInit_ex() failed");
@@ -131,7 +131,7 @@ digest_reset(PX_MD *h)
 static void
 digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 {
-	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+	OSSLDigest *digest = (OSSLDigest *) h->ptr;
 
 	if (!EVP_DigestUpdate(digest->ctx, data, dlen))
 		elog(ERROR, "EVP_DigestUpdate() failed");
@@ -140,7 +140,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
 static void
 digest_finish(PX_MD *h, uint8 *dst)
 {
-	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+	OSSLDigest *digest = (OSSLDigest *) h->ptr;
 
 	if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))
 		elog(ERROR, "EVP_DigestFinal_ex() failed");
@@ -149,7 +149,7 @@ digest_finish(PX_MD *h, uint8 *dst)
 static void
 digest_free(PX_MD *h)
 {
-	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+	OSSLDigest *digest = (OSSLDigest *) h->ptr;
 
 	free_openssl_digest(digest);
 	pfree(h);
@@ -204,7 +204,7 @@ px_find_digest(const char *name, PX_MD **res)
 	h->update = digest_update;
 	h->finish = digest_finish;
 	h->free = digest_free;
-	h->p.ptr = digest;
+	h->ptr = digest;
 
 	*res = h;
 	return 0;
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
index 4b81fceab8e..7846a63f301 100644
--- a/contrib/pgcrypto/px.h
+++ b/contrib/pgcrypto/px.h
@@ -117,7 +117,7 @@ struct px_digest
 	{
 		unsigned	code;
 		void	   *ptr;
-	}			p;
+	};
 };
 
 struct px_alias
-- 
2.51.0

From d70d5d570bda08ba01c18f732e4786714cd14b82 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 04/23] C11 anonymous unions [plpython]

---
 src/pl/plpython/plpy_exec.c   |   2 +-
 src/pl/plpython/plpy_typeio.c | 134 +++++++++++++++++-----------------
 src/pl/plpython/plpy_typeio.h |   4 +-
 3 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c
index fd06b9e0e4e..0117f1e77ef 100644
--- a/src/pl/plpython/plpy_exec.c
+++ b/src/pl/plpython/plpy_exec.c
@@ -1046,7 +1046,7 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
 			Py_INCREF(plval);
 
 			/* We assume proc->result is set up to convert tuples properly */
-			att = &proc->result.u.tuple.atts[attn - 1];
+			att = &proc->result.tuple.atts[attn - 1];
 
 			modvalues[attn - 1] = PLy_output_convert(att,
 													 plval,
diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c
index f6509a41902..bba78fb7592 100644
--- a/src/pl/plpython/plpy_typeio.c
+++ b/src/pl/plpython/plpy_typeio.c
@@ -171,15 +171,15 @@ PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, PLyProcedure *proc)
 
 	/* Save pointer to tupdesc, but only if this is an anonymous record type */
 	if (arg->typoid == RECORDOID && arg->typmod < 0)
-		arg->u.tuple.recdesc = desc;
+		arg->tuple.recdesc = desc;
 
 	/* (Re)allocate atts array as needed */
-	if (arg->u.tuple.natts != desc->natts)
+	if (arg->tuple.natts != desc->natts)
 	{
-		if (arg->u.tuple.atts)
-			pfree(arg->u.tuple.atts);
-		arg->u.tuple.natts = desc->natts;
-		arg->u.tuple.atts = (PLyDatumToOb *)
+		if (arg->tuple.atts)
+			pfree(arg->tuple.atts);
+		arg->tuple.natts = desc->natts;
+		arg->tuple.atts = (PLyDatumToOb *)
 			MemoryContextAllocZero(arg->mcxt,
 								   desc->natts * sizeof(PLyDatumToOb));
 	}
@@ -188,7 +188,7 @@ PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, PLyProcedure *proc)
 	for (i = 0; i < desc->natts; i++)
 	{
 		Form_pg_attribute attr = TupleDescAttr(desc, i);
-		PLyDatumToOb *att = &arg->u.tuple.atts[i];
+		PLyDatumToOb *att = &arg->tuple.atts[i];
 
 		if (attr->attisdropped)
 			continue;
@@ -221,15 +221,15 @@ PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, PLyProcedure *proc)
 
 	/* Save pointer to tupdesc, but only if this is an anonymous record type */
 	if (arg->typoid == RECORDOID && arg->typmod < 0)
-		arg->u.tuple.recdesc = desc;
+		arg->tuple.recdesc = desc;
 
 	/* (Re)allocate atts array as needed */
-	if (arg->u.tuple.natts != desc->natts)
+	if (arg->tuple.natts != desc->natts)
 	{
-		if (arg->u.tuple.atts)
-			pfree(arg->u.tuple.atts);
-		arg->u.tuple.natts = desc->natts;
-		arg->u.tuple.atts = (PLyObToDatum *)
+		if (arg->tuple.atts)
+			pfree(arg->tuple.atts);
+		arg->tuple.natts = desc->natts;
+		arg->tuple.atts = (PLyObToDatum *)
 			MemoryContextAllocZero(arg->mcxt,
 								   desc->natts * sizeof(PLyObToDatum));
 	}
@@ -238,7 +238,7 @@ PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, PLyProcedure *proc)
 	for (i = 0; i < desc->natts; i++)
 	{
 		Form_pg_attribute attr = TupleDescAttr(desc, i);
-		PLyObToDatum *att = &arg->u.tuple.atts[i];
+		PLyObToDatum *att = &arg->tuple.atts[i];
 
 		if (attr->attisdropped)
 			continue;
@@ -277,9 +277,9 @@ PLy_output_setup_record(PLyObToDatum *arg, TupleDesc desc, PLyProcedure *proc)
 	 * for the record type.
 	 */
 	arg->typmod = desc->tdtypmod;
-	if (arg->u.tuple.recdesc &&
-		arg->u.tuple.recdesc->tdtypmod != arg->typmod)
-		arg->u.tuple.recdesc = NULL;
+	if (arg->tuple.recdesc &&
+		arg->tuple.recdesc->tdtypmod != arg->typmod)
+		arg->tuple.recdesc = NULL;
 
 	/* Update derived data if necessary */
 	PLy_output_setup_tuple(arg, desc, proc);
@@ -343,11 +343,11 @@ PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt,
 	{
 		/* Domain */
 		arg->func = PLyObject_ToDomain;
-		arg->u.domain.domain_info = NULL;
+		arg->domain.domain_info = NULL;
 		/* Recursively set up conversion info for the element type */
-		arg->u.domain.base = (PLyObToDatum *)
+		arg->domain.base = (PLyObToDatum *)
 			MemoryContextAllocZero(arg_mcxt, sizeof(PLyObToDatum));
-		PLy_output_setup_func(arg->u.domain.base, arg_mcxt,
+		PLy_output_setup_func(arg->domain.base, arg_mcxt,
 							  typentry->domainBaseType,
 							  typentry->domainBaseTypmod,
 							  proc);
@@ -359,11 +359,11 @@ PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt,
 		arg->func = PLySequence_ToArray;
 		/* Get base type OID to insert into constructed array */
 		/* (note this might not be the same as the immediate child type) */
-		arg->u.array.elmbasetype = getBaseType(typentry->typelem);
+		arg->array.elmbasetype = getBaseType(typentry->typelem);
 		/* Recursively set up conversion info for the element type */
-		arg->u.array.elm = (PLyObToDatum *)
+		arg->array.elm = (PLyObToDatum *)
 			MemoryContextAllocZero(arg_mcxt, sizeof(PLyObToDatum));
-		PLy_output_setup_func(arg->u.array.elm, arg_mcxt,
+		PLy_output_setup_func(arg->array.elm, arg_mcxt,
 							  typentry->typelem, typmod,
 							  proc);
 	}
@@ -372,20 +372,20 @@ PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt,
 											 proc->trftypes)))
 	{
 		arg->func = PLyObject_ToTransform;
-		fmgr_info_cxt(trfuncid, &arg->u.transform.typtransform, arg_mcxt);
+		fmgr_info_cxt(trfuncid, &arg->transform.typtransform, arg_mcxt);
 	}
 	else if (typtype == TYPTYPE_COMPOSITE)
 	{
 		/* Named composite type, or RECORD */
 		arg->func = PLyObject_ToComposite;
 		/* We'll set up the per-field data later */
-		arg->u.tuple.recdesc = NULL;
-		arg->u.tuple.typentry = typentry;
-		arg->u.tuple.tupdescid = INVALID_TUPLEDESC_IDENTIFIER;
-		arg->u.tuple.atts = NULL;
-		arg->u.tuple.natts = 0;
+		arg->tuple.recdesc = NULL;
+		arg->tuple.typentry = typentry;
+		arg->tuple.tupdescid = INVALID_TUPLEDESC_IDENTIFIER;
+		arg->tuple.atts = NULL;
+		arg->tuple.natts = 0;
 		/* Mark this invalid till needed, too */
-		arg->u.tuple.recinfunc.fn_oid = InvalidOid;
+		arg->tuple.recinfunc.fn_oid = InvalidOid;
 	}
 	else
 	{
@@ -400,8 +400,8 @@ PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt,
 				break;
 			default:
 				arg->func = PLyObject_ToScalar;
-				getTypeInputInfo(typeOid, &typinput, &arg->u.scalar.typioparam);
-				fmgr_info_cxt(typinput, &arg->u.scalar.typfunc, arg_mcxt);
+				getTypeInputInfo(typeOid, &typinput, &arg->scalar.typioparam);
+				fmgr_info_cxt(typinput, &arg->scalar.typfunc, arg_mcxt);
 				break;
 		}
 	}
@@ -476,9 +476,9 @@ PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt,
 		/* Standard array */
 		arg->func = PLyList_FromArray;
 		/* Recursively set up conversion info for the element type */
-		arg->u.array.elm = (PLyDatumToOb *)
+		arg->array.elm = (PLyDatumToOb *)
 			MemoryContextAllocZero(arg_mcxt, sizeof(PLyDatumToOb));
-		PLy_input_setup_func(arg->u.array.elm, arg_mcxt,
+		PLy_input_setup_func(arg->array.elm, arg_mcxt,
 							 typentry->typelem, typmod,
 							 proc);
 	}
@@ -487,18 +487,18 @@ PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt,
 											   proc->trftypes)))
 	{
 		arg->func = PLyObject_FromTransform;
-		fmgr_info_cxt(trfuncid, &arg->u.transform.typtransform, arg_mcxt);
+		fmgr_info_cxt(trfuncid, &arg->transform.typtransform, arg_mcxt);
 	}
 	else if (typtype == TYPTYPE_COMPOSITE)
 	{
 		/* Named composite type, or RECORD */
 		arg->func = PLyDict_FromComposite;
 		/* We'll set up the per-field data later */
-		arg->u.tuple.recdesc = NULL;
-		arg->u.tuple.typentry = typentry;
-		arg->u.tuple.tupdescid = INVALID_TUPLEDESC_IDENTIFIER;
-		arg->u.tuple.atts = NULL;
-		arg->u.tuple.natts = 0;
+		arg->tuple.recdesc = NULL;
+		arg->tuple.typentry = typentry;
+		arg->tuple.tupdescid = INVALID_TUPLEDESC_IDENTIFIER;
+		arg->tuple.atts = NULL;
+		arg->tuple.natts = 0;
 	}
 	else
 	{
@@ -535,7 +535,7 @@ PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt,
 			default:
 				arg->func = PLyUnicode_FromScalar;
 				getTypeOutputInfo(typeOid, &typoutput, &typisvarlena);
-				fmgr_info_cxt(typoutput, &arg->u.scalar.typfunc, arg_mcxt);
+				fmgr_info_cxt(typoutput, &arg->scalar.typfunc, arg_mcxt);
 				break;
 		}
 	}
@@ -641,7 +641,7 @@ PLyBytes_FromBytea(PLyDatumToOb *arg, Datum d)
 static PyObject *
 PLyUnicode_FromScalar(PLyDatumToOb *arg, Datum d)
 {
-	char	   *x = OutputFunctionCall(&arg->u.scalar.typfunc, d);
+	char	   *x = OutputFunctionCall(&arg->scalar.typfunc, d);
 	PyObject   *r = PLyUnicode_FromString(x);
 
 	pfree(x);
@@ -656,7 +656,7 @@ PLyObject_FromTransform(PLyDatumToOb *arg, Datum d)
 {
 	Datum		t;
 
-	t = FunctionCall1(&arg->u.transform.typtransform, d);
+	t = FunctionCall1(&arg->transform.typtransform, d);
 	return (PyObject *) DatumGetPointer(t);
 }
 
@@ -667,7 +667,7 @@ static PyObject *
 PLyList_FromArray(PLyDatumToOb *arg, Datum d)
 {
 	ArrayType  *array = DatumGetArrayTypeP(d);
-	PLyDatumToOb *elm = arg->u.array.elm;
+	PLyDatumToOb *elm = arg->array.elm;
 	int			ndim;
 	int		   *dims;
 	char	   *dataptr;
@@ -817,7 +817,7 @@ PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool inclu
 	PyObject   *volatile dict;
 
 	/* Simple sanity check that desc matches */
-	Assert(desc->natts == arg->u.tuple.natts);
+	Assert(desc->natts == arg->tuple.natts);
 
 	dict = PyDict_New();
 	if (dict == NULL)
@@ -827,9 +827,9 @@ PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool inclu
 	{
 		int			i;
 
-		for (i = 0; i < arg->u.tuple.natts; i++)
+		for (i = 0; i < arg->tuple.natts; i++)
 		{
-			PLyDatumToOb *att = &arg->u.tuple.atts[i];
+			PLyDatumToOb *att = &arg->tuple.atts[i];
 			Form_pg_attribute attr = TupleDescAttr(desc, i);
 			char	   *key;
 			Datum		vattr;
@@ -971,22 +971,22 @@ PLyObject_ToComposite(PLyObToDatum *arg, PyObject *plrv,
 	{
 		desc = lookup_rowtype_tupdesc(arg->typoid, arg->typmod);
 		/* We should have the descriptor of the type's typcache entry */
-		Assert(desc == arg->u.tuple.typentry->tupDesc);
+		Assert(desc == arg->tuple.typentry->tupDesc);
 		/* Detect change of descriptor, update cache if needed */
-		if (arg->u.tuple.tupdescid != arg->u.tuple.typentry->tupDesc_identifier)
+		if (arg->tuple.tupdescid != arg->tuple.typentry->tupDesc_identifier)
 		{
 			PLy_output_setup_tuple(arg, desc,
 								   PLy_current_execution_context()->curr_proc);
-			arg->u.tuple.tupdescid = arg->u.tuple.typentry->tupDesc_identifier;
+			arg->tuple.tupdescid = arg->tuple.typentry->tupDesc_identifier;
 		}
 	}
 	else
 	{
-		desc = arg->u.tuple.recdesc;
+		desc = arg->tuple.recdesc;
 		if (desc == NULL)
 		{
 			desc = lookup_rowtype_tupdesc(arg->typoid, arg->typmod);
-			arg->u.tuple.recdesc = desc;
+			arg->tuple.recdesc = desc;
 		}
 		else
 		{
@@ -996,7 +996,7 @@ PLyObject_ToComposite(PLyObToDatum *arg, PyObject *plrv,
 	}
 
 	/* Simple sanity check on our caching */
-	Assert(desc->natts == arg->u.tuple.natts);
+	Assert(desc->natts == arg->tuple.natts);
 
 	/*
 	 * Convert, using the appropriate method depending on the type of the
@@ -1088,9 +1088,9 @@ PLyObject_ToScalar(PLyObToDatum *arg, PyObject *plrv,
 
 	str = PLyObject_AsString(plrv);
 
-	return InputFunctionCall(&arg->u.scalar.typfunc,
+	return InputFunctionCall(&arg->scalar.typfunc,
 							 str,
-							 arg->u.scalar.typioparam,
+							 arg->scalar.typioparam,
 							 arg->typmod);
 }
 
@@ -1103,11 +1103,11 @@ PLyObject_ToDomain(PLyObToDatum *arg, PyObject *plrv,
 				   bool *isnull, bool inarray)
 {
 	Datum		result;
-	PLyObToDatum *base = arg->u.domain.base;
+	PLyObToDatum *base = arg->domain.base;
 
 	result = base->func(base, plrv, isnull, inarray);
 	domain_check(result, *isnull, arg->typoid,
-				 &arg->u.domain.domain_info, arg->mcxt);
+				 &arg->domain.domain_info, arg->mcxt);
 	return result;
 }
 
@@ -1125,7 +1125,7 @@ PLyObject_ToTransform(PLyObToDatum *arg, PyObject *plrv,
 		return (Datum) 0;
 	}
 	*isnull = false;
-	return FunctionCall1(&arg->u.transform.typtransform, PointerGetDatum(plrv));
+	return FunctionCall1(&arg->transform.typtransform, PointerGetDatum(plrv));
 }

@@ -1169,12 +1169,12 @@ PLySequence_ToArray(PLyObToDatum *arg, PyObject *plrv,
 	 */
 	PLySequence_ToArray_recurse(plrv, &astate,
 								&ndims, dims, 1,
-								arg->u.array.elm,
-								arg->u.array.elmbasetype);
+								arg->array.elm,
+								arg->array.elmbasetype);
 
 	/* ensure we get zero-D array for no inputs, as per PG convention */
 	if (astate == NULL)
-		return PointerGetDatum(construct_empty_array(arg->u.array.elmbasetype));
+		return PointerGetDatum(construct_empty_array(arg->array.elmbasetype));
 
 	for (int i = 0; i < ndims; i++)
 		lbs[i] = 1;
@@ -1289,8 +1289,8 @@ PLyUnicode_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray)
 	 * Set up call data for record_in, if we didn't already.  (We can't just
 	 * use DirectFunctionCall, because record_in needs a fn_extra field.)
 	 */
-	if (!OidIsValid(arg->u.tuple.recinfunc.fn_oid))
-		fmgr_info_cxt(F_RECORD_IN, &arg->u.tuple.recinfunc, arg->mcxt);
+	if (!OidIsValid(arg->tuple.recinfunc.fn_oid))
+		fmgr_info_cxt(F_RECORD_IN, &arg->tuple.recinfunc, arg->mcxt);
 
 	str = PLyObject_AsString(string);
 
@@ -1334,7 +1334,7 @@ PLyUnicode_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray)
 					 errhint("To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\".")));
 	}
 
-	return InputFunctionCall(&arg->u.tuple.recinfunc,
+	return InputFunctionCall(&arg->tuple.recinfunc,
 							 str,
 							 arg->typoid,
 							 arg->typmod);
@@ -1371,7 +1371,7 @@ PLyMapping_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *mapping)
 
 		key = NameStr(attr->attname);
 		value = NULL;
-		att = &arg->u.tuple.atts[i];
+		att = &arg->tuple.atts[i];
 		PG_TRY();
 		{
 			value = PyMapping_GetItemString(mapping, key);
@@ -1451,7 +1451,7 @@ PLySequence_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *sequence)
 		}
 
 		value = NULL;
-		att = &arg->u.tuple.atts[i];
+		att = &arg->tuple.atts[i];
 		PG_TRY();
 		{
 			value = PySequence_GetItem(sequence, idx);
@@ -1511,7 +1511,7 @@ PLyGenericObject_ToComposite(PLyObToDatum *arg, TupleDesc desc, PyObject *object
 
 		key = NameStr(attr->attname);
 		value = NULL;
-		att = &arg->u.tuple.atts[i];
+		att = &arg->tuple.atts[i];
 		PG_TRY();
 		{
 			value = PyObject_GetAttrString(object, key);
diff --git a/src/pl/plpython/plpy_typeio.h b/src/pl/plpython/plpy_typeio.h
index 5417f0945d2..29258509b5c 100644
--- a/src/pl/plpython/plpy_typeio.h
+++ b/src/pl/plpython/plpy_typeio.h
@@ -69,7 +69,7 @@ struct PLyDatumToOb
 		PLyArrayToOb array;
 		PLyTupleToOb tuple;
 		PLyTransformToOb transform;
-	}			u;
+	};
 };
 
 /*
@@ -143,7 +143,7 @@ struct PLyObToDatum
 		PLyObToTuple tuple;
 		PLyObToDomain domain;
 		PLyObToTransform transform;
-	}			u;
+	};
 };

-- 
2.51.0

From 4709c40820a25151bc6426d43319d746ee384371 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 05/23] C11 anonymous unions [libpq]

---
 src/interfaces/libpq/fe-lobj.c      | 44 ++++++++++++++---------------
 src/interfaces/libpq/fe-protocol3.c |  4 +--
 src/interfaces/libpq/libpq-fe.h     |  4 +--
 3 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 05e17bed508..1546b770f6e 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -66,11 +66,11 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = lobjId;
+	argv[0].integer = lobjId;
 
 	argv[1].isint = 1;
 	argv[1].len = 4;
-	argv[1].u.integer = mode;
+	argv[1].integer = mode;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -105,7 +105,7 @@ lo_close(PGconn *conn, int fd)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
 			   &retval, &result_len, 1, argv, 1);
 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -163,11 +163,11 @@ lo_truncate(PGconn *conn, int fd, size_t len)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	argv[1].isint = 1;
 	argv[1].len = 4;
-	argv[1].u.integer = (int) len;
+	argv[1].integer = (int) len;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
 			   &retval, &result_len, 1, argv, 2);
@@ -211,12 +211,12 @@ lo_truncate64(PGconn *conn, int fd, int64_t len)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	len = lo_hton64(len);
 	argv[1].isint = 0;
 	argv[1].len = 8;
-	argv[1].u.ptr = (int *) &len;
+	argv[1].ptr = (int *) &len;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
 			   &retval, &result_len, 1, argv, 2);
@@ -265,11 +265,11 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	argv[1].isint = 1;
 	argv[1].len = 4;
-	argv[1].u.integer = (int) len;
+	argv[1].integer = (int) len;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
 			   (void *) buf, &result_len, 0, argv, 2);
@@ -316,11 +316,11 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	argv[1].isint = 0;
 	argv[1].len = (int) len;
-	argv[1].u.ptr = (int *) unconstify(char *, buf);
+	argv[1].ptr = (int *) unconstify(char *, buf);
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
 			   &retval, &result_len, 1, argv, 2);
@@ -353,15 +353,15 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	argv[1].isint = 1;
 	argv[1].len = 4;
-	argv[1].u.integer = offset;
+	argv[1].integer = offset;
 
 	argv[2].isint = 1;
 	argv[2].len = 4;
-	argv[2].u.integer = whence;
+	argv[2].integer = whence;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
 			   &retval, &result_len, 1, argv, 3);
@@ -401,16 +401,16 @@ lo_lseek64(PGconn *conn, int fd, int64_t offset, int whence)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	offset = lo_hton64(offset);
 	argv[1].isint = 0;
 	argv[1].len = 8;
-	argv[1].u.ptr = (int *) &offset;
+	argv[1].ptr = (int *) &offset;
 
 	argv[2].isint = 1;
 	argv[2].len = 4;
-	argv[2].u.integer = whence;
+	argv[2].integer = whence;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
 			   (void *) &retval, &result_len, 0, argv, 3);
@@ -447,7 +447,7 @@ lo_creat(PGconn *conn, int mode)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = mode;
+	argv[0].integer = mode;
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
 			   &retval, &result_len, 1, argv, 1);
 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -491,7 +491,7 @@ lo_create(PGconn *conn, Oid lobjId)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = lobjId;
+	argv[0].integer = lobjId;
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
 			   &retval, &result_len, 1, argv, 1);
 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -524,7 +524,7 @@ lo_tell(PGconn *conn, int fd)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
 			   &retval, &result_len, 1, argv, 1);
@@ -564,7 +564,7 @@ lo_tell64(PGconn *conn, int fd)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = fd;
+	argv[0].integer = fd;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
 			   (void *) &retval, &result_len, 0, argv, 1);
@@ -598,7 +598,7 @@ lo_unlink(PGconn *conn, Oid lobjId)
 
 	argv[0].isint = 1;
 	argv[0].len = 4;
-	argv[0].u.integer = lobjId;
+	argv[0].integer = lobjId;
 
 	res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
 			   &retval, &result_len, 1, argv, 1);
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index da7a8db68c8..c941a4c1664 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2175,12 +2175,12 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
 
 		if (args[i].isint)
 		{
-			if (pqPutInt(args[i].u.integer, args[i].len, conn))
+			if (pqPutInt(args[i].integer, args[i].len, conn))
 				return NULL;
 		}
 		else
 		{
-			if (pqPutnchar(args[i].u.ptr, args[i].len, conn))
+			if (pqPutnchar(args[i].ptr, args[i].len, conn))
 				return NULL;
 		}
 	}
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 0852584edae..83d5c071097 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -293,9 +293,9 @@ typedef struct
 	int			isint;
 	union
 	{
-		int		   *ptr;		/* can't use void (dec compiler barfs)	 */
+		void	   *ptr;
 		int			integer;
-	}			u;
+	};
 } PQArgBlock;
 
 /* ----------------
-- 
2.51.0

From 97a249ab66884d23780790caf18cbe03cd94f3fc Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 06/23] C11 anonymous unions [reorderbuffer data]

---
 contrib/test_decoding/test_decoding.c         |  24 +-
 src/backend/replication/logical/decode.c      |  54 ++--
 .../replication/logical/reorderbuffer.c       | 254 +++++++++---------
 src/backend/replication/pgoutput/pgoutput.c   |  14 +-
 src/include/replication/reorderbuffer.h       |   2 +-
 5 files changed, 174 insertions(+), 174 deletions(-)

diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c
index 36e77c69e1c..1723651b770 100644
--- a/contrib/test_decoding/test_decoding.c
+++ b/contrib/test_decoding/test_decoding.c
@@ -639,41 +639,41 @@ pg_decode_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 	{
 		case REORDER_BUFFER_CHANGE_INSERT:
 			appendStringInfoString(ctx->out, " INSERT:");
-			if (change->data.tp.newtuple == NULL)
+			if (change->tp.newtuple == NULL)
 				appendStringInfoString(ctx->out, " (no-tuple-data)");
 			else
 				tuple_to_stringinfo(ctx->out, tupdesc,
-									change->data.tp.newtuple,
+									change->tp.newtuple,
 									false);
 			break;
 		case REORDER_BUFFER_CHANGE_UPDATE:
 			appendStringInfoString(ctx->out, " UPDATE:");
-			if (change->data.tp.oldtuple != NULL)
+			if (change->tp.oldtuple != NULL)
 			{
 				appendStringInfoString(ctx->out, " old-key:");
 				tuple_to_stringinfo(ctx->out, tupdesc,
-									change->data.tp.oldtuple,
+									change->tp.oldtuple,
 									true);
 				appendStringInfoString(ctx->out, " new-tuple:");
 			}
 
-			if (change->data.tp.newtuple == NULL)
+			if (change->tp.newtuple == NULL)
 				appendStringInfoString(ctx->out, " (no-tuple-data)");
 			else
 				tuple_to_stringinfo(ctx->out, tupdesc,
-									change->data.tp.newtuple,
+									change->tp.newtuple,
 									false);
 			break;
 		case REORDER_BUFFER_CHANGE_DELETE:
 			appendStringInfoString(ctx->out, " DELETE:");
 
 			/* if there was no PK, we only know that a delete happened */
-			if (change->data.tp.oldtuple == NULL)
+			if (change->tp.oldtuple == NULL)
 				appendStringInfoString(ctx->out, " (no-tuple-data)");
 			/* In DELETE, only the replica identity is present; display that */
 			else
 				tuple_to_stringinfo(ctx->out, tupdesc,
-									change->data.tp.oldtuple,
+									change->tp.oldtuple,
 									true);
 			break;
 		default:
@@ -724,12 +724,12 @@ pg_decode_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 
 	appendStringInfoString(ctx->out, ": TRUNCATE:");
 
-	if (change->data.truncate.restart_seqs
-		|| change->data.truncate.cascade)
+	if (change->truncate.restart_seqs
+		|| change->truncate.cascade)
 	{
-		if (change->data.truncate.restart_seqs)
+		if (change->truncate.restart_seqs)
 			appendStringInfoString(ctx->out, " restart_seqs");
-		if (change->data.truncate.cascade)
+		if (change->truncate.cascade)
 			appendStringInfoString(ctx->out, " cascade");
 	}
 	else
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index cc03f0706e9..f7773e38dda 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -935,17 +935,17 @@ DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		change->action = REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT;
 	change->origin_id = XLogRecGetOrigin(r);
 
-	memcpy(&change->data.tp.rlocator, &target_locator, sizeof(RelFileLocator));
+	memcpy(&change->tp.rlocator, &target_locator, sizeof(RelFileLocator));
 
 	tupledata = XLogRecGetBlockData(r, 0, &datalen);
 	tuplelen = datalen - SizeOfHeapHeader;
 
-	change->data.tp.newtuple =
+	change->tp.newtuple =
 		ReorderBufferAllocTupleBuf(ctx->reorder, tuplelen);
 
-	DecodeXLogTuple(tupledata, datalen, change->data.tp.newtuple);
+	DecodeXLogTuple(tupledata, datalen, change->tp.newtuple);
 
-	change->data.tp.clear_toast_afterwards = true;
+	change->tp.clear_toast_afterwards = true;
 
 	ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r), buf->origptr,
 							 change,
@@ -981,7 +981,7 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 	change = ReorderBufferAllocChange(ctx->reorder);
 	change->action = REORDER_BUFFER_CHANGE_UPDATE;
 	change->origin_id = XLogRecGetOrigin(r);
-	memcpy(&change->data.tp.rlocator, &target_locator, sizeof(RelFileLocator));
+	memcpy(&change->tp.rlocator, &target_locator, sizeof(RelFileLocator));
 
 	if (xlrec->flags & XLH_UPDATE_CONTAINS_NEW_TUPLE)
 	{
@@ -992,10 +992,10 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 
 		tuplelen = datalen - SizeOfHeapHeader;
 
-		change->data.tp.newtuple =
+		change->tp.newtuple =
 			ReorderBufferAllocTupleBuf(ctx->reorder, tuplelen);
 
-		DecodeXLogTuple(data, datalen, change->data.tp.newtuple);
+		DecodeXLogTuple(data, datalen, change->tp.newtuple);
 	}
 
 	if (xlrec->flags & XLH_UPDATE_CONTAINS_OLD)
@@ -1008,13 +1008,13 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		datalen = XLogRecGetDataLen(r) - SizeOfHeapUpdate;
 		tuplelen = datalen - SizeOfHeapHeader;
 
-		change->data.tp.oldtuple =
+		change->tp.oldtuple =
 			ReorderBufferAllocTupleBuf(ctx->reorder, tuplelen);
 
-		DecodeXLogTuple(data, datalen, change->data.tp.oldtuple);
+		DecodeXLogTuple(data, datalen, change->tp.oldtuple);
 	}
 
-	change->data.tp.clear_toast_afterwards = true;
+	change->tp.clear_toast_afterwards = true;
 
 	ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r), buf->origptr,
 							 change, false);
@@ -1053,7 +1053,7 @@ DecodeDelete(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 
 	change->origin_id = XLogRecGetOrigin(r);
 
-	memcpy(&change->data.tp.rlocator, &target_locator, sizeof(RelFileLocator));
+	memcpy(&change->tp.rlocator, &target_locator, sizeof(RelFileLocator));
 
 	/* old primary key stored */
 	if (xlrec->flags & XLH_DELETE_CONTAINS_OLD)
@@ -1063,14 +1063,14 @@ DecodeDelete(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 
 		Assert(XLogRecGetDataLen(r) > (SizeOfHeapDelete + SizeOfHeapHeader));
 
-		change->data.tp.oldtuple =
+		change->tp.oldtuple =
 			ReorderBufferAllocTupleBuf(ctx->reorder, tuplelen);
 
 		DecodeXLogTuple((char *) xlrec + SizeOfHeapDelete,
-						datalen, change->data.tp.oldtuple);
+						datalen, change->tp.oldtuple);
 	}
 
-	change->data.tp.clear_toast_afterwards = true;
+	change->tp.clear_toast_afterwards = true;
 
 	ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r), buf->origptr,
 							 change, false);
@@ -1100,13 +1100,13 @@ DecodeTruncate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 	change->action = REORDER_BUFFER_CHANGE_TRUNCATE;
 	change->origin_id = XLogRecGetOrigin(r);
 	if (xlrec->flags & XLH_TRUNCATE_CASCADE)
-		change->data.truncate.cascade = true;
+		change->truncate.cascade = true;
 	if (xlrec->flags & XLH_TRUNCATE_RESTART_SEQS)
-		change->data.truncate.restart_seqs = true;
-	change->data.truncate.nrelids = xlrec->nrelids;
-	change->data.truncate.relids = ReorderBufferAllocRelids(ctx->reorder,
-															xlrec->nrelids);
-	memcpy(change->data.truncate.relids, xlrec->relids,
+		change->truncate.restart_seqs = true;
+	change->truncate.nrelids = xlrec->nrelids;
+	change->truncate.relids = ReorderBufferAllocRelids(ctx->reorder,
+													   xlrec->nrelids);
+	memcpy(change->truncate.relids, xlrec->relids,
 		   xlrec->nrelids * sizeof(Oid));
 	ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r),
 							 buf->origptr, change, false);
@@ -1166,16 +1166,16 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		change->action = REORDER_BUFFER_CHANGE_INSERT;
 		change->origin_id = XLogRecGetOrigin(r);
 
-		memcpy(&change->data.tp.rlocator, &rlocator, sizeof(RelFileLocator));
+		memcpy(&change->tp.rlocator, &rlocator, sizeof(RelFileLocator));
 
 		xlhdr = (xl_multi_insert_tuple *) SHORTALIGN(data);
 		data = ((char *) xlhdr) + SizeOfMultiInsertTuple;
 		datalen = xlhdr->datalen;
 
-		change->data.tp.newtuple =
+		change->tp.newtuple =
 			ReorderBufferAllocTupleBuf(ctx->reorder, datalen);
 
-		tuple = change->data.tp.newtuple;
+		tuple = change->tp.newtuple;
 		header = tuple->t_data;
 
 		/* not a disk based tuple */
@@ -1202,9 +1202,9 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		 */
 		if (xlrec->flags & XLH_INSERT_LAST_IN_MULTI &&
 			(i + 1) == xlrec->ntuples)
-			change->data.tp.clear_toast_afterwards = true;
+			change->tp.clear_toast_afterwards = true;
 		else
-			change->data.tp.clear_toast_afterwards = false;
+			change->tp.clear_toast_afterwards = false;
 
 		ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r),
 								 buf->origptr, change, false);
@@ -1241,9 +1241,9 @@ DecodeSpecConfirm(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 	change->action = REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM;
 	change->origin_id = XLogRecGetOrigin(r);
 
-	memcpy(&change->data.tp.rlocator, &target_locator, sizeof(RelFileLocator));
+	memcpy(&change->tp.rlocator, &target_locator, sizeof(RelFileLocator));
 
-	change->data.tp.clear_toast_afterwards = true;
+	change->tp.clear_toast_afterwards = true;
 
 	ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r), buf->origptr,
 							 change, false);
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index a5e165fb123..afde2c5c208 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -533,44 +533,44 @@ ReorderBufferFreeChange(ReorderBuffer *rb, ReorderBufferChange *change,
 		case REORDER_BUFFER_CHANGE_UPDATE:
 		case REORDER_BUFFER_CHANGE_DELETE:
 		case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT:
-			if (change->data.tp.newtuple)
+			if (change->tp.newtuple)
 			{
-				ReorderBufferFreeTupleBuf(change->data.tp.newtuple);
-				change->data.tp.newtuple = NULL;
+				ReorderBufferFreeTupleBuf(change->tp.newtuple);
+				change->tp.newtuple = NULL;
 			}
 
-			if (change->data.tp.oldtuple)
+			if (change->tp.oldtuple)
 			{
-				ReorderBufferFreeTupleBuf(change->data.tp.oldtuple);
-				change->data.tp.oldtuple = NULL;
+				ReorderBufferFreeTupleBuf(change->tp.oldtuple);
+				change->tp.oldtuple = NULL;
 			}
 			break;
 		case REORDER_BUFFER_CHANGE_MESSAGE:
-			if (change->data.msg.prefix != NULL)
-				pfree(change->data.msg.prefix);
-			change->data.msg.prefix = NULL;
-			if (change->data.msg.message != NULL)
-				pfree(change->data.msg.message);
-			change->data.msg.message = NULL;
+			if (change->msg.prefix != NULL)
+				pfree(change->msg.prefix);
+			change->msg.prefix = NULL;
+			if (change->msg.message != NULL)
+				pfree(change->msg.message);
+			change->msg.message = NULL;
 			break;
 		case REORDER_BUFFER_CHANGE_INVALIDATION:
-			if (change->data.inval.invalidations)
-				pfree(change->data.inval.invalidations);
-			change->data.inval.invalidations = NULL;
+			if (change->inval.invalidations)
+				pfree(change->inval.invalidations);
+			change->inval.invalidations = NULL;
 			break;
 		case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
-			if (change->data.snapshot)
+			if (change->snapshot)
 			{
-				ReorderBufferFreeSnap(rb, change->data.snapshot);
-				change->data.snapshot = NULL;
+				ReorderBufferFreeSnap(rb, change->snapshot);
+				change->snapshot = NULL;
 			}
 			break;
 			/* no data in addition to the struct itself */
 		case REORDER_BUFFER_CHANGE_TRUNCATE:
-			if (change->data.truncate.relids != NULL)
+			if (change->truncate.relids != NULL)
 			{
-				ReorderBufferFreeRelids(rb, change->data.truncate.relids);
-				change->data.truncate.relids = NULL;
+				ReorderBufferFreeRelids(rb, change->truncate.relids);
+				change->truncate.relids = NULL;
 			}
 			break;
 		case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM:
@@ -771,7 +771,7 @@ ReorderBufferProcessPartialChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 		toptxn->txn_flags |= RBTXN_HAS_PARTIAL_CHANGE;
 	else if (rbtxn_has_partial_change(toptxn) &&
 			 IsInsertOrUpdate(change->action) &&
-			 change->data.tp.clear_toast_afterwards)
+			 change->tp.clear_toast_afterwards)
 		toptxn->txn_flags &= ~RBTXN_HAS_PARTIAL_CHANGE;
 
 	/*
@@ -892,10 +892,10 @@ ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid,
 
 		change = ReorderBufferAllocChange(rb);
 		change->action = REORDER_BUFFER_CHANGE_MESSAGE;
-		change->data.msg.prefix = pstrdup(prefix);
-		change->data.msg.message_size = message_size;
-		change->data.msg.message = palloc(message_size);
-		memcpy(change->data.msg.message, message, message_size);
+		change->msg.prefix = pstrdup(prefix);
+		change->msg.message_size = message_size;
+		change->msg.message = palloc(message_size);
+		memcpy(change->msg.message, message, message_size);
 
 		ReorderBufferQueueChange(rb, xid, lsn, change, false);
 
@@ -1866,18 +1866,18 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn)
 		/* be careful about padding */
 		memset(&key, 0, sizeof(ReorderBufferTupleCidKey));
 
-		key.rlocator = change->data.tuplecid.locator;
+		key.rlocator = change->tuplecid.locator;
 
-		ItemPointerCopy(&change->data.tuplecid.tid,
+		ItemPointerCopy(&change->tuplecid.tid,
 						&key.tid);
 
 		ent = (ReorderBufferTupleCidEnt *)
 			hash_search(txn->tuplecid_hash, &key, HASH_ENTER, &found);
 		if (!found)
 		{
-			ent->cmin = change->data.tuplecid.cmin;
-			ent->cmax = change->data.tuplecid.cmax;
-			ent->combocid = change->data.tuplecid.combocid;
+			ent->cmin = change->tuplecid.cmin;
+			ent->cmax = change->tuplecid.cmax;
+			ent->combocid = change->tuplecid.combocid;
 		}
 		else
 		{
@@ -1885,16 +1885,16 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn)
 			 * Maybe we already saw this tuple before in this transaction, but
 			 * if so it must have the same cmin.
 			 */
-			Assert(ent->cmin == change->data.tuplecid.cmin);
+			Assert(ent->cmin == change->tuplecid.cmin);
 
 			/*
 			 * cmax may be initially invalid, but once set it can only grow,
 			 * and never become invalid again.
 			 */
 			Assert((ent->cmax == InvalidCommandId) ||
-				   ((change->data.tuplecid.cmax != InvalidCommandId) &&
-					(change->data.tuplecid.cmax > ent->cmax)));
-			ent->cmax = change->data.tuplecid.cmax;
+				   ((change->tuplecid.cmax != InvalidCommandId) &&
+					(change->tuplecid.cmax > ent->cmax)));
+			ent->cmax = change->tuplecid.cmax;
 		}
 	}
 }
@@ -2101,14 +2101,14 @@ ReorderBufferApplyMessage(ReorderBuffer *rb, ReorderBufferTXN *txn,
 {
 	if (streaming)
 		rb->stream_message(rb, txn, change->lsn, true,
-						   change->data.msg.prefix,
-						   change->data.msg.message_size,
-						   change->data.msg.message);
+						   change->msg.prefix,
+						   change->msg.message_size,
+						   change->msg.message);
 	else
 		rb->message(rb, txn, change->lsn, true,
-					change->data.msg.prefix,
-					change->data.msg.message_size,
-					change->data.msg.message);
+					change->msg.prefix,
+					change->msg.message_size,
+					change->msg.message);
 }
 
 /*
@@ -2316,7 +2316,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					 */
 					if (specinsert == NULL)
 						elog(ERROR, "invalid ordering of speculative insertion changes");
-					Assert(specinsert->data.tp.oldtuple == NULL);
+					Assert(specinsert->tp.oldtuple == NULL);
 					change = specinsert;
 					change->action = REORDER_BUFFER_CHANGE_INSERT;
 
@@ -2326,8 +2326,8 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				case REORDER_BUFFER_CHANGE_DELETE:
 					Assert(snapshot_now);
 
-					reloid = RelidByRelfilenumber(change->data.tp.rlocator.spcOid,
-												  change->data.tp.rlocator.relNumber);
+					reloid = RelidByRelfilenumber(change->tp.rlocator.spcOid,
+												  change->tp.rlocator.relNumber);
 
 					/*
 					 * Mapped catalog tuple without data, emitted while
@@ -2342,12 +2342,12 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					 * mapping the relfilenumber to the oid.
 					 */
 					if (reloid == InvalidOid &&
-						change->data.tp.newtuple == NULL &&
-						change->data.tp.oldtuple == NULL)
+						change->tp.newtuple == NULL &&
+						change->tp.oldtuple == NULL)
 						goto change_done;
 					else if (reloid == InvalidOid)
 						elog(ERROR, "could not map filenumber \"%s\" to relation OID",
-							 relpathperm(change->data.tp.rlocator,
+							 relpathperm(change->tp.rlocator,
 										 MAIN_FORKNUM).str);
 
 					relation = RelationIdGetRelation(reloid);
@@ -2355,7 +2355,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					if (!RelationIsValid(relation))
 						elog(ERROR, "could not open relation with OID %u (for filenumber \"%s\")",
 							 reloid,
-							 relpathperm(change->data.tp.rlocator,
+							 relpathperm(change->tp.rlocator,
 										 MAIN_FORKNUM).str);
 
 					if (!RelationIsLogicallyLogged(relation))
@@ -2389,7 +2389,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 						 * they're not required anymore. The creator of the
 						 * tuple tells us.
 						 */
-						if (change->data.tp.clear_toast_afterwards)
+						if (change->tp.clear_toast_afterwards)
 							ReorderBufferToastReset(rb, txn);
 					}
 					/* we're not interested in toast deletions */
@@ -2403,7 +2403,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 						 * freed/reused while restoring spooled data from
 						 * disk.
 						 */
-						Assert(change->data.tp.newtuple != NULL);
+						Assert(change->tp.newtuple != NULL);
 
 						dlist_delete(&change->node);
 						ReorderBufferToastAppendChunk(rb, txn, relation,
@@ -2473,7 +2473,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 						 * completely new tuple to avoid confusion about the
 						 * previous tuple's toast chunks.
 						 */
-						Assert(change->data.tp.clear_toast_afterwards);
+						Assert(change->tp.clear_toast_afterwards);
 						ReorderBufferToastReset(rb, txn);
 
 						/* We don't need this record anymore. */
@@ -2485,14 +2485,14 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				case REORDER_BUFFER_CHANGE_TRUNCATE:
 					{
 						int			i;
-						int			nrelids = change->data.truncate.nrelids;
+						int			nrelids = change->truncate.nrelids;
 						int			nrelations = 0;
 						Relation   *relations;
 
 						relations = palloc0(nrelids * sizeof(Relation));
 						for (i = 0; i < nrelids; i++)
 						{
-							Oid			relid = change->data.truncate.relids[i];
+							Oid			relid = change->truncate.relids[i];
 							Relation	rel;
 
 							rel = RelationIdGetRelation(relid);
@@ -2523,8 +2523,8 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 
 				case REORDER_BUFFER_CHANGE_INVALIDATION:
 					/* Execute the invalidation messages locally */
-					ReorderBufferExecuteInvalidations(change->data.inval.ninvalidations,
-													  change->data.inval.invalidations);
+					ReorderBufferExecuteInvalidations(change->inval.ninvalidations,
+													  change->inval.invalidations);
 					break;
 
 				case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
@@ -2535,7 +2535,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					{
 						ReorderBufferFreeSnap(rb, snapshot_now);
 						snapshot_now =
-							ReorderBufferCopySnap(rb, change->data.snapshot,
+							ReorderBufferCopySnap(rb, change->snapshot,
 												  txn, command_id);
 					}
 
@@ -2544,15 +2544,15 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					 * free. We could introduce refcounting for that, but for
 					 * now this seems infrequent enough not to care.
 					 */
-					else if (change->data.snapshot->copied)
+					else if (change->snapshot->copied)
 					{
 						snapshot_now =
-							ReorderBufferCopySnap(rb, change->data.snapshot,
+							ReorderBufferCopySnap(rb, change->snapshot,
 												  txn, command_id);
 					}
 					else
 					{
-						snapshot_now = change->data.snapshot;
+						snapshot_now = change->snapshot;
 					}
 
 					/* and continue with the new one */
@@ -2560,11 +2560,11 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					break;
 
 				case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID:
-					Assert(change->data.command_id != InvalidCommandId);
+					Assert(change->command_id != InvalidCommandId);
 
-					if (command_id < change->data.command_id)
+					if (command_id < change->command_id)
 					{
-						command_id = change->data.command_id;
+						command_id = change->command_id;
 
 						if (!snapshot_now->copied)
 						{
@@ -3309,7 +3309,7 @@ ReorderBufferAddSnapshot(ReorderBuffer *rb, TransactionId xid,
 {
 	ReorderBufferChange *change = ReorderBufferAllocChange(rb);
 
-	change->data.snapshot = snap;
+	change->snapshot = snap;
 	change->action = REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT;
 
 	ReorderBufferQueueChange(rb, xid, lsn, change, false);
@@ -3358,7 +3358,7 @@ ReorderBufferAddNewCommandId(ReorderBuffer *rb, TransactionId xid,
 {
 	ReorderBufferChange *change = ReorderBufferAllocChange(rb);
 
-	change->data.command_id = cid;
+	change->command_id = cid;
 	change->action = REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID;
 
 	ReorderBufferQueueChange(rb, xid, lsn, change, false);
@@ -3462,11 +3462,11 @@ ReorderBufferAddNewTupleCids(ReorderBuffer *rb, TransactionId xid,
 
 	txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true);
 
-	change->data.tuplecid.locator = locator;
-	change->data.tuplecid.tid = tid;
-	change->data.tuplecid.cmin = cmin;
-	change->data.tuplecid.cmax = cmax;
-	change->data.tuplecid.combocid = combocid;
+	change->tuplecid.locator = locator;
+	change->tuplecid.tid = tid;
+	change->tuplecid.cmin = cmin;
+	change->tuplecid.cmax = cmax;
+	change->tuplecid.combocid = combocid;
 	change->lsn = lsn;
 	change->txn = txn;
 	change->action = REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID;
@@ -3487,10 +3487,10 @@ ReorderBufferQueueInvalidations(ReorderBuffer *rb, TransactionId xid,
 
 	change = ReorderBufferAllocChange(rb);
 	change->action = REORDER_BUFFER_CHANGE_INVALIDATION;
-	change->data.inval.ninvalidations = nmsgs;
-	change->data.inval.invalidations = (SharedInvalidationMessage *)
+	change->inval.ninvalidations = nmsgs;
+	change->inval.invalidations = (SharedInvalidationMessage *)
 		palloc(sizeof(SharedInvalidationMessage) * nmsgs);
-	memcpy(change->data.inval.invalidations, msgs,
+	memcpy(change->inval.invalidations, msgs,
 		   sizeof(SharedInvalidationMessage) * nmsgs);
 
 	ReorderBufferQueueChange(rb, xid, lsn, change, false);
@@ -4095,8 +4095,8 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				Size		oldlen = 0;
 				Size		newlen = 0;
 
-				oldtup = change->data.tp.oldtuple;
-				newtup = change->data.tp.newtuple;
+				oldtup = change->tp.oldtuple;
+				newtup = change->tp.newtuple;
 
 				if (oldtup)
 				{
@@ -4141,9 +4141,9 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 		case REORDER_BUFFER_CHANGE_MESSAGE:
 			{
 				char	   *data;
-				Size		prefix_size = strlen(change->data.msg.prefix) + 1;
+				Size		prefix_size = strlen(change->msg.prefix) + 1;
 
-				sz += prefix_size + change->data.msg.message_size +
+				sz += prefix_size + change->msg.message_size +
 					sizeof(Size) + sizeof(Size);
 				ReorderBufferSerializeReserve(rb, sz);
 
@@ -4155,16 +4155,16 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				/* write the prefix including the size */
 				memcpy(data, &prefix_size, sizeof(Size));
 				data += sizeof(Size);
-				memcpy(data, change->data.msg.prefix,
+				memcpy(data, change->msg.prefix,
 					   prefix_size);
 				data += prefix_size;
 
 				/* write the message including the size */
-				memcpy(data, &change->data.msg.message_size, sizeof(Size));
+				memcpy(data, &change->msg.message_size, sizeof(Size));
 				data += sizeof(Size);
-				memcpy(data, change->data.msg.message,
-					   change->data.msg.message_size);
-				data += change->data.msg.message_size;
+				memcpy(data, change->msg.message,
+					   change->msg.message_size);
+				data += change->msg.message_size;
 
 				break;
 			}
@@ -4172,7 +4172,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 			{
 				char	   *data;
 				Size		inval_size = sizeof(SharedInvalidationMessage) *
-					change->data.inval.ninvalidations;
+					change->inval.ninvalidations;
 
 				sz += inval_size;
 
@@ -4181,7 +4181,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 
 				/* might have been reallocated above */
 				ondisk = (ReorderBufferDiskChange *) rb->outbuf;
-				memcpy(data, change->data.inval.invalidations, inval_size);
+				memcpy(data, change->inval.invalidations, inval_size);
 				data += inval_size;
 
 				break;
@@ -4191,7 +4191,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				Snapshot	snap;
 				char	   *data;
 
-				snap = change->data.snapshot;
+				snap = change->snapshot;
 
 				sz += sizeof(SnapshotData) +
 					sizeof(TransactionId) * snap->xcnt +
@@ -4227,7 +4227,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				char	   *data;
 
 				/* account for the OIDs of truncated relations */
-				size = sizeof(Oid) * change->data.truncate.nrelids;
+				size = sizeof(Oid) * change->truncate.nrelids;
 				sz += size;
 
 				/* make sure we have enough space */
@@ -4237,7 +4237,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				/* might have been reallocated above */
 				ondisk = (ReorderBufferDiskChange *) rb->outbuf;
 
-				memcpy(data, change->data.truncate.relids, size);
+				memcpy(data, change->truncate.relids, size);
 				data += size;
 
 				break;
@@ -4454,8 +4454,8 @@ ReorderBufferChangeSize(ReorderBufferChange *change)
 				Size		oldlen = 0;
 				Size		newlen = 0;
 
-				oldtup = change->data.tp.oldtuple;
-				newtup = change->data.tp.newtuple;
+				oldtup = change->tp.oldtuple;
+				newtup = change->tp.newtuple;
 
 				if (oldtup)
 				{
@@ -4475,9 +4475,9 @@ ReorderBufferChangeSize(ReorderBufferChange *change)
 			}
 		case REORDER_BUFFER_CHANGE_MESSAGE:
 			{
-				Size		prefix_size = strlen(change->data.msg.prefix) + 1;
+				Size		prefix_size = strlen(change->msg.prefix) + 1;
 
-				sz += prefix_size + change->data.msg.message_size +
+				sz += prefix_size + change->msg.message_size +
 					sizeof(Size) + sizeof(Size);
 
 				break;
@@ -4485,14 +4485,14 @@ ReorderBufferChangeSize(ReorderBufferChange *change)
 		case REORDER_BUFFER_CHANGE_INVALIDATION:
 			{
 				sz += sizeof(SharedInvalidationMessage) *
-					change->data.inval.ninvalidations;
+					change->inval.ninvalidations;
 				break;
 			}
 		case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
 			{
 				Snapshot	snap;
 
-				snap = change->data.snapshot;
+				snap = change->snapshot;
 
 				sz += sizeof(SnapshotData) +
 					sizeof(TransactionId) * snap->xcnt +
@@ -4502,7 +4502,7 @@ ReorderBufferChangeSize(ReorderBufferChange *change)
 			}
 		case REORDER_BUFFER_CHANGE_TRUNCATE:
 			{
-				sz += sizeof(Oid) * change->data.truncate.nrelids;
+				sz += sizeof(Oid) * change->truncate.nrelids;
 
 				break;
 			}
@@ -4688,28 +4688,28 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 		case REORDER_BUFFER_CHANGE_UPDATE:
 		case REORDER_BUFFER_CHANGE_DELETE:
 		case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT:
-			if (change->data.tp.oldtuple)
+			if (change->tp.oldtuple)
 			{
 				uint32		tuplelen = ((HeapTuple) data)->t_len;
 
-				change->data.tp.oldtuple =
+				change->tp.oldtuple =
 					ReorderBufferAllocTupleBuf(rb, tuplelen - SizeofHeapTupleHeader);
 
 				/* restore ->tuple */
-				memcpy(change->data.tp.oldtuple, data,
+				memcpy(change->tp.oldtuple, data,
 					   sizeof(HeapTupleData));
 				data += sizeof(HeapTupleData);
 
 				/* reset t_data pointer into the new tuplebuf */
-				change->data.tp.oldtuple->t_data =
-					(HeapTupleHeader) ((char *) change->data.tp.oldtuple + HEAPTUPLESIZE);
+				change->tp.oldtuple->t_data =
+					(HeapTupleHeader) ((char *) change->tp.oldtuple + HEAPTUPLESIZE);
 
 				/* restore tuple data itself */
-				memcpy(change->data.tp.oldtuple->t_data, data, tuplelen);
+				memcpy(change->tp.oldtuple->t_data, data, tuplelen);
 				data += tuplelen;
 			}
 
-			if (change->data.tp.newtuple)
+			if (change->tp.newtuple)
 			{
 				/* here, data might not be suitably aligned! */
 				uint32		tuplelen;
@@ -4717,20 +4717,20 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				memcpy(&tuplelen, data + offsetof(HeapTupleData, t_len),
 					   sizeof(uint32));
 
-				change->data.tp.newtuple =
+				change->tp.newtuple =
 					ReorderBufferAllocTupleBuf(rb, tuplelen - SizeofHeapTupleHeader);
 
 				/* restore ->tuple */
-				memcpy(change->data.tp.newtuple, data,
+				memcpy(change->tp.newtuple, data,
 					   sizeof(HeapTupleData));
 				data += sizeof(HeapTupleData);
 
 				/* reset t_data pointer into the new tuplebuf */
-				change->data.tp.newtuple->t_data =
-					(HeapTupleHeader) ((char *) change->data.tp.newtuple + HEAPTUPLESIZE);
+				change->tp.newtuple->t_data =
+					(HeapTupleHeader) ((char *) change->tp.newtuple + HEAPTUPLESIZE);
 
 				/* restore tuple data itself */
-				memcpy(change->data.tp.newtuple->t_data, data, tuplelen);
+				memcpy(change->tp.newtuple->t_data, data, tuplelen);
 				data += tuplelen;
 			}
 
@@ -4742,33 +4742,33 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 				/* read prefix */
 				memcpy(&prefix_size, data, sizeof(Size));
 				data += sizeof(Size);
-				change->data.msg.prefix = MemoryContextAlloc(rb->context,
-															 prefix_size);
-				memcpy(change->data.msg.prefix, data, prefix_size);
-				Assert(change->data.msg.prefix[prefix_size - 1] == '\0');
+				change->msg.prefix = MemoryContextAlloc(rb->context,
+														prefix_size);
+				memcpy(change->msg.prefix, data, prefix_size);
+				Assert(change->msg.prefix[prefix_size - 1] == '\0');
 				data += prefix_size;
 
 				/* read the message */
-				memcpy(&change->data.msg.message_size, data, sizeof(Size));
+				memcpy(&change->msg.message_size, data, sizeof(Size));
 				data += sizeof(Size);
-				change->data.msg.message = MemoryContextAlloc(rb->context,
-															  change->data.msg.message_size);
-				memcpy(change->data.msg.message, data,
-					   change->data.msg.message_size);
-				data += change->data.msg.message_size;
+				change->msg.message = MemoryContextAlloc(rb->context,
+														 change->msg.message_size);
+				memcpy(change->msg.message, data,
+					   change->msg.message_size);
+				data += change->msg.message_size;
 
 				break;
 			}
 		case REORDER_BUFFER_CHANGE_INVALIDATION:
 			{
 				Size		inval_size = sizeof(SharedInvalidationMessage) *
-					change->data.inval.ninvalidations;
+					change->inval.ninvalidations;
 
-				change->data.inval.invalidations =
+				change->inval.invalidations =
 					MemoryContextAlloc(rb->context, inval_size);
 
 				/* read the message */
-				memcpy(change->data.inval.invalidations, data, inval_size);
+				memcpy(change->inval.invalidations, data, inval_size);
 
 				break;
 			}
@@ -4784,9 +4784,9 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 					sizeof(TransactionId) * oldsnap->xcnt +
 					sizeof(TransactionId) * (oldsnap->subxcnt + 0);
 
-				change->data.snapshot = MemoryContextAllocZero(rb->context, size);
+				change->snapshot = MemoryContextAllocZero(rb->context, size);
 
-				newsnap = change->data.snapshot;
+				newsnap = change->snapshot;
 
 				memcpy(newsnap, data, size);
 				newsnap->xip = (TransactionId *)
@@ -4800,9 +4800,9 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 			{
 				Oid		   *relids;
 
-				relids = ReorderBufferAllocRelids(rb, change->data.truncate.nrelids);
-				memcpy(relids, data, change->data.truncate.nrelids * sizeof(Oid));
-				change->data.truncate.relids = relids;
+				relids = ReorderBufferAllocRelids(rb, change->truncate.nrelids);
+				memcpy(relids, data, change->truncate.nrelids * sizeof(Oid));
+				change->truncate.relids = relids;
 
 				break;
 			}
@@ -4991,7 +4991,7 @@ ReorderBufferToastAppendChunk(ReorderBuffer *rb, ReorderBufferTXN *txn,
 
 	Assert(IsToastRelation(relation));
 
-	newtup = change->data.tp.newtuple;
+	newtup = change->tp.newtuple;
 	chunk_id = DatumGetObjectId(fastgetattr(newtup, 1, desc, &isnull));
 	Assert(!isnull);
 	chunk_seq = DatumGetInt32(fastgetattr(newtup, 2, desc, &isnull));
@@ -5090,7 +5090,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
 	oldcontext = MemoryContextSwitchTo(rb->context);
 
 	/* we should only have toast tuples in an INSERT or UPDATE */
-	Assert(change->data.tp.newtuple);
+	Assert(change->tp.newtuple);
 
 	desc = RelationGetDescr(relation);
 
@@ -5106,7 +5106,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
 	isnull = palloc0(sizeof(bool) * desc->natts);
 	free = palloc0(sizeof(bool) * desc->natts);
 
-	newtup = change->data.tp.newtuple;
+	newtup = change->tp.newtuple;
 
 	heap_deform_tuple(newtup, desc, attrs, isnull);
 
@@ -5177,7 +5177,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
 			Pointer		chunk;
 
 			cchange = dlist_container(ReorderBufferChange, node, it.cur);
-			ctup = cchange->data.tp.newtuple;
+			ctup = cchange->tp.newtuple;
 			chunk = DatumGetPointer(fastgetattr(ctup, 3, toast_desc, &cisnull));
 
 			Assert(!cisnull);
diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 92eb17049c3..7cd93c21964 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -1502,7 +1502,7 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 			 * identity is not defined for a table. Since the DELETE action
 			 * can't be published, we simply return.
 			 */
-			if (!change->data.tp.oldtuple)
+			if (!change->tp.oldtuple)
 			{
 				elog(DEBUG1, "didn't send DELETE change because of missing oldtuple");
 				return;
@@ -1523,10 +1523,10 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 		targetrel = ancestor;
 	}
 
-	if (change->data.tp.oldtuple)
+	if (change->tp.oldtuple)
 	{
 		old_slot = relentry->old_slot;
-		ExecStoreHeapTuple(change->data.tp.oldtuple, old_slot, false);
+		ExecStoreHeapTuple(change->tp.oldtuple, old_slot, false);
 
 		/* Convert tuple if needed. */
 		if (relentry->attrmap)
@@ -1538,10 +1538,10 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 		}
 	}
 
-	if (change->data.tp.newtuple)
+	if (change->tp.newtuple)
 	{
 		new_slot = relentry->new_slot;
-		ExecStoreHeapTuple(change->data.tp.newtuple, new_slot, false);
+		ExecStoreHeapTuple(change->tp.newtuple, new_slot, false);
 
 		/* Convert tuple if needed. */
 		if (relentry->attrmap)
@@ -1684,8 +1684,8 @@ pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 								  xid,
 								  nrelids,
 								  relids,
-								  change->data.truncate.cascade,
-								  change->data.truncate.restart_seqs);
+								  change->truncate.cascade,
+								  change->truncate.restart_seqs);
 		OutputPluginWrite(ctx, true);
 	}
 
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index 91dc7e5e448..bbbdf098c71 100644
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -154,7 +154,7 @@ typedef struct ReorderBufferChange
 			uint32		ninvalidations; /* Number of messages */
 			SharedInvalidationMessage *invalidations;	/* invalidation message */
 		}			inval;
-	}			data;
+	};
 
 	/*
 	 * While in use this is how a change is linked into a transactions,
-- 
2.51.0

From 0ed789f5b05c8e12f7bc2c71caeb23628c701291 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 07/23] C11 anonymous unions [ecpg]

---
 src/interfaces/ecpg/preproc/descriptor.c |  2 +-
 src/interfaces/ecpg/preproc/ecpg.header  | 60 ++++++++++++------------
 src/interfaces/ecpg/preproc/ecpg.trailer |  4 +-
 src/interfaces/ecpg/preproc/type.c       | 46 +++++++++---------
 src/interfaces/ecpg/preproc/type.h       |  2 +-
 src/interfaces/ecpg/preproc/variable.c   | 42 ++++++++---------
 6 files changed, 78 insertions(+), 78 deletions(-)

diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c
index e8c7016bdc1..2f682880fd2 100644
--- a/src/interfaces/ecpg/preproc/descriptor.c
+++ b/src/interfaces/ecpg/preproc/descriptor.c
@@ -357,7 +357,7 @@ sqlda_variable(const char *name)
 	p->type->type_name = NULL;
 	p->type->size = NULL;
 	p->type->struct_sizeof = NULL;
-	p->type->u.element = NULL;
+	p->type->element = NULL;
 	p->type->counter = 0;
 	p->brace_level = 0;
 	p->next = NULL;
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index dde69a39695..37487853a70 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -150,14 +150,14 @@ create_questionmarks(const char *name, bool array)
 	 * parameter is an error anywhere else so we don't have to worry here.
 	 */
 
-	if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
+	if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->element->type == ECPGt_struct))
 	{
 		struct ECPGstruct_member *m;
 
 		if (p->type->type == ECPGt_struct)
-			m = p->type->u.members;
+			m = p->type->members;
 		else
-			m = p->type->u.element->u.members;
+			m = p->type->element->members;
 
 		for (count = 0; m != NULL; m = m->next, count++);
 	}
@@ -236,12 +236,12 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
 					 && atoi(ptr->variable->type->size) > 1)
 			{
 				newvar = new_variable(cat_str(4, "(",
-											  ecpg_type_name(ptr->variable->type->u.element->type),
+											  ecpg_type_name(ptr->variable->type->element->type),
 											  " *)(ECPGget_var(",
 											  var_text),
-									  ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type,
+									  ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->element->type,
 																			   "1",
-																			   ptr->variable->type->u.element->counter),
+																			   ptr->variable->type->element->counter),
 														  ptr->variable->type->size),
 									  0);
 			}
@@ -272,7 +272,7 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
 											  " *)(ECPGget_var(",
 											  var_text,
 											  ")"),
-									  ECPGmake_struct_type(ptr->variable->type->u.members,
+									  ECPGmake_struct_type(ptr->variable->type->members,
 														   ptr->variable->type->type,
 														   ptr->variable->type->type_name,
 														   ptr->variable->type->struct_sizeof),
@@ -281,29 +281,29 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
 			}
 			else if (ptr->variable->type->type == ECPGt_array)
 			{
-				if (ptr->variable->type->u.element->type == ECPGt_struct
-					|| ptr->variable->type->u.element->type == ECPGt_union)
+				if (ptr->variable->type->element->type == ECPGt_struct
+					|| ptr->variable->type->element->type == ECPGt_union)
 				{
 					newvar = new_variable(cat_str(5, "(*(",
-												  ptr->variable->type->u.element->type_name,
+												  ptr->variable->type->element->type_name,
 												  " *)(ECPGget_var(",
 												  var_text,
 												  ")"),
-										  ECPGmake_struct_type(ptr->variable->type->u.element->u.members,
-															   ptr->variable->type->u.element->type,
-															   ptr->variable->type->u.element->type_name,
-															   ptr->variable->type->u.element->struct_sizeof),
+										  ECPGmake_struct_type(ptr->variable->type->element->members,
+															   ptr->variable->type->element->type,
+															   ptr->variable->type->element->type_name,
+															   ptr->variable->type->element->struct_sizeof),
 										  0);
 				}
 				else
 				{
 					newvar = new_variable(cat_str(4, "(",
-												  ecpg_type_name(ptr->variable->type->u.element->type),
+												  ecpg_type_name(ptr->variable->type->element->type),
 												  " *)(ECPGget_var(",
 												  var_text),
-										  ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type,
-																				   ptr->variable->type->u.element->size,
-																				   ptr->variable->type->u.element->counter),
+										  ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->element->type,
+																				   ptr->variable->type->element->size,
+																				   ptr->variable->type->element->counter),
 															  ptr->variable->type->size),
 										  0);
 					var_ptr = true;
@@ -358,7 +358,7 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
 												  " *)(ECPGget_var(",
 												  var_text,
 												  ")"),
-										  ECPGmake_struct_type(ptr->indicator->type->u.members,
+										  ECPGmake_struct_type(ptr->indicator->type->members,
 															   ptr->indicator->type->type,
 															   ptr->indicator->type->type_name,
 															   ptr->indicator->type->struct_sizeof),
@@ -367,29 +367,29 @@ adjust_outofscope_cursor_vars(struct cursor *cur)
 				}
 				else if (ptr->indicator->type->type == ECPGt_array)
 				{
-					if (ptr->indicator->type->u.element->type == ECPGt_struct
-						|| ptr->indicator->type->u.element->type == ECPGt_union)
+					if (ptr->indicator->type->element->type == ECPGt_struct
+						|| ptr->indicator->type->element->type == ECPGt_union)
 					{
 						newind = new_variable(cat_str(5, "(*(",
-													  ptr->indicator->type->u.element->type_name,
+													  ptr->indicator->type->element->type_name,
 													  " *)(ECPGget_var(",
 													  var_text,
 													  ")"),
-											  ECPGmake_struct_type(ptr->indicator->type->u.element->u.members,
-																   ptr->indicator->type->u.element->type,
-																   ptr->indicator->type->u.element->type_name,
-																   ptr->indicator->type->u.element->struct_sizeof),
+											  ECPGmake_struct_type(ptr->indicator->type->element->members,
+																   ptr->indicator->type->element->type,
+																   ptr->indicator->type->element->type_name,
+																   ptr->indicator->type->element->struct_sizeof),
 											  0);
 					}
 					else
 					{
 						newind = new_variable(cat_str(4, "(",
-													  ecpg_type_name(ptr->indicator->type->u.element->type),
+													  ecpg_type_name(ptr->indicator->type->element->type),
 													  " *)(ECPGget_var(",
 													  var_text),
-											  ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->u.element->type,
-																					   ptr->indicator->type->u.element->size,
-																					   ptr->indicator->type->u.element->counter),
+											  ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->element->type,
+																					   ptr->indicator->type->element->size,
+																					   ptr->indicator->type->element->counter),
 																  ptr->indicator->type->size),
 											  0);
 						var_ptr = true;
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 6f94b832a03..5064cba8091 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -255,7 +255,7 @@ user_name: RoleId
 
 		/* if array see what's inside */
 		if (type == ECPGt_array)
-			type = argsinsert->variable->type->u.element->type;
+			type = argsinsert->variable->type->element->type;
 
 		/* handle varchars */
 		if (type == ECPGt_varchar)
@@ -278,7 +278,7 @@ char_variable: cvariable
 		{
 			/* if array see what's inside */
 			if (type == ECPGt_array)
-				type = p->type->u.element->type;
+				type = p->type->element->type;
 
 			switch (type)
 			{
diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c
index 9f6dacd2aea..87d7735b227 100644
--- a/src/interfaces/ecpg/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -22,7 +22,7 @@ ECPGstruct_member_dup(struct ECPGstruct_member *rm)
 		{
 			case ECPGt_struct:
 			case ECPGt_union:
-				type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->type_name, rm->type->struct_sizeof);
+				type = ECPGmake_struct_type(rm->type->members, rm->type->type, rm->type->type_name, rm->type->struct_sizeof);
 				break;
 			case ECPGt_array:
 
@@ -30,10 +30,10 @@ ECPGstruct_member_dup(struct ECPGstruct_member *rm)
 				 * if this array does contain a struct again, we have to
 				 * create the struct too
 				 */
-				if (rm->type->u.element->type == ECPGt_struct || rm->type->u.element->type == ECPGt_union)
-					type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->type_name, rm->type->u.element->struct_sizeof);
+				if (rm->type->element->type == ECPGt_struct || rm->type->element->type == ECPGt_union)
+					type = ECPGmake_struct_type(rm->type->element->members, rm->type->element->type, rm->type->element->type_name, rm->type->element->struct_sizeof);
 				else
-					type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->counter), rm->type->size);
+					type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->element->type, rm->type->element->size, rm->type->element->counter), rm->type->size);
 				break;
 			default:
 				type = ECPGmake_simple_type(rm->type->type, rm->type->size, rm->type->counter);
@@ -76,7 +76,7 @@ ECPGmake_simple_type(enum ECPGttype type, const char *size, int counter)
 	ne->type = type;
 	ne->type_name = NULL;
 	ne->size = mm_strdup(size);
-	ne->u.element = NULL;
+	ne->element = NULL;
 	ne->struct_sizeof = NULL;
 	ne->counter = counter;		/* only needed for varchar and bytea */
 
@@ -88,7 +88,7 @@ ECPGmake_array_type(struct ECPGtype *type, const char *size)
 {
 	struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, size, 0);
 
-	ne->u.element = type;
+	ne->element = type;
 
 	return ne;
 }
@@ -100,7 +100,7 @@ ECPGmake_struct_type(struct ECPGstruct_member *rm, enum ECPGttype type,
 	struct ECPGtype *ne = ECPGmake_simple_type(type, "1", 0);
 
 	ne->type_name = mm_strdup(type_name);
-	ne->u.members = ECPGstruct_member_dup(rm);
+	ne->members = ECPGstruct_member_dup(rm);
 	ne->struct_sizeof = mm_strdup(struct_sizeof);
 
 	return ne;
@@ -262,7 +262,7 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *type, const int brac
 		case ECPGt_array:
 			if (indicator_set && ind_type->type != ECPGt_array)
 				mmfatal(INDICATOR_NOT_ARRAY, "indicator for array/pointer has to be array/pointer");
-			switch (type->u.element->type)
+			switch (type->element->type)
 			{
 				case ECPGt_array:
 					mmerror(PARSE_ERROR, ET_ERROR, "nested arrays are not supported (except strings)"); /* array of array */
@@ -272,18 +272,18 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *type, const int brac
 					ECPGdump_a_struct(o, name,
 									  ind_name,
 									  type->size,
-									  type->u.element,
-									  (ind_type == NULL) ? NULL : ((ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element),
+									  type->element,
+									  (ind_type == NULL) ? NULL : ((ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->element),
 									  prefix, ind_prefix);
 					break;
 				default:
-					if (!IS_SIMPLE_TYPE(type->u.element->type))
+					if (!IS_SIMPLE_TYPE(type->element->type))
 						base_yyerror("internal error: unknown datatype, please report this to <" PACKAGE_BUGREPORT ">");
 
 					ECPGdump_a_simple(o, name,
-									  type->u.element->type,
-									  type->u.element->size, type->size, struct_sizeof ? struct_sizeof : NULL,
-									  prefix, type->u.element->counter);
+									  type->element->type,
+									  type->element->size, type->size, struct_sizeof ? struct_sizeof : NULL,
+									  prefix, type->element->counter);
 
 					if (ind_type != NULL)
 					{
@@ -296,8 +296,8 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *type, const int brac
 						}
 						else
 						{
-							ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
-											  ind_type->u.element->size, ind_type->size, NULL, ind_prefix, 0);
+							ECPGdump_a_simple(o, ind_name, ind_type->element->type,
+											  ind_type->element->size, ind_type->size, NULL, ind_prefix, 0);
 						}
 					}
 			}
@@ -583,10 +583,10 @@ ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize
 			sprintf(ind_pbuf, "%s%s->", ind_prefix ? ind_prefix : "", ind_name);
 
 		ind_prefix = ind_pbuf;
-		ind_p = ind_type->u.members;
+		ind_p = ind_type->members;
 	}
 
-	for (p = type->u.members; p; p = p->next)
+	for (p = type->members; p; p = p->next)
 	{
 		ECPGdump_a_type(o, p->name, p->type, -1,
 						(ind_p != NULL) ? ind_p->name : NULL,
@@ -636,7 +636,7 @@ ECPGfree_type(struct ECPGtype *type)
 		switch (type->type)
 		{
 			case ECPGt_array:
-				switch (type->u.element->type)
+				switch (type->element->type)
 				{
 					case ECPGt_array:
 						base_yyerror("internal error: found multidimensional array\n");
@@ -644,18 +644,18 @@ ECPGfree_type(struct ECPGtype *type)
 					case ECPGt_struct:
 					case ECPGt_union:
 						/* Array of structs. */
-						ECPGfree_type(type->u.element);
+						ECPGfree_type(type->element);
 						break;
 					default:
-						if (!IS_SIMPLE_TYPE(type->u.element->type))
+						if (!IS_SIMPLE_TYPE(type->element->type))
 							base_yyerror("internal error: unknown datatype, please report this to <" PACKAGE_BUGREPORT ">");
 
-						ECPGfree_type(type->u.element);
+						ECPGfree_type(type->element);
 				}
 				break;
 			case ECPGt_struct:
 			case ECPGt_union:
-				ECPGfree_struct_member(type->u.members);
+				ECPGfree_struct_member(type->members);
 				break;
 			default:
 				mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type->type);
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index 3d99e1703de..776dd32e5d6 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -28,7 +28,7 @@ struct ECPGtype
 		struct ECPGtype *element;	/* For an array this is the type of the
 									 * element */
 		struct ECPGstruct_member *members;	/* A pointer to a list of members. */
-	}			u;
+	};
 	int			counter;
 };
 
diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c
index 2c67e33e92e..84605e36d0c 100644
--- a/src/interfaces/ecpg/preproc/variable.c
+++ b/src/interfaces/ecpg/preproc/variable.c
@@ -44,10 +44,10 @@ find_struct_member(const char *name, char *str, struct ECPGstruct_member *member
 				switch (members->type->type)
 				{
 					case ECPGt_array:
-						return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), members->type->size), brace_level);
+						return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->element->type, members->type->element->size, members->type->element->counter), members->type->size), brace_level);
 					case ECPGt_struct:
 					case ECPGt_union:
-						return new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level);
+						return new_variable(name, ECPGmake_struct_type(members->type->members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level);
 					default:
 						return new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->counter), brace_level);
 				}
@@ -88,28 +88,28 @@ find_struct_member(const char *name, char *str, struct ECPGstruct_member *member
 						if (members->type->type != ECPGt_array)
 							mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
 
-						switch (members->type->u.element->type)
+						switch (members->type->element->type)
 						{
 							case ECPGt_array:
-								return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->counter), members->type->u.element->size), brace_level);
+								return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->element->element->type, members->type->element->element->size, members->type->element->element->counter), members->type->element->size), brace_level);
 							case ECPGt_struct:
 							case ECPGt_union:
-								return new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->type_name, members->type->u.element->struct_sizeof), brace_level);
+								return new_variable(name, ECPGmake_struct_type(members->type->element->members, members->type->element->type, members->type->element->type_name, members->type->element->struct_sizeof), brace_level);
 							default:
-								return new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), brace_level);
+								return new_variable(name, ECPGmake_simple_type(members->type->element->type, members->type->element->size, members->type->element->counter), brace_level);
 						}
 						break;
 					case '-':
 						if (members->type->type == ECPGt_array)
-							return find_struct_member(name, ++end, members->type->u.element->u.members, brace_level);
+							return find_struct_member(name, ++end, members->type->element->members, brace_level);
 						else
-							return find_struct_member(name, ++end, members->type->u.members, brace_level);
+							return find_struct_member(name, ++end, members->type->members, brace_level);
 						break;
 					case '.':
 						if (members->type->type == ECPGt_array)
-							return find_struct_member(name, end, members->type->u.element->u.members, brace_level);
+							return find_struct_member(name, end, members->type->element->members, brace_level);
 						else
-							return find_struct_member(name, end, members->type->u.members, brace_level);
+							return find_struct_member(name, end, members->type->members, brace_level);
 						break;
 					default:
 						mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
@@ -137,13 +137,13 @@ find_struct(const char *name, char *next, char *end)
 		if (p->type->type != ECPGt_array)
 			mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", name);
 
-		if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
+		if (p->type->element->type != ECPGt_struct && p->type->element->type != ECPGt_union)
 			mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
 
 		/* restore the name, we will need it later */
 		*next = c;
 
-		return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level);
+		return find_struct_member(name, ++end, p->type->element->members, p->brace_level);
 	}
 	else
 	{
@@ -155,20 +155,20 @@ find_struct(const char *name, char *next, char *end)
 			/* restore the name, we will need it later */
 			*next = c;
 
-			return find_struct_member(name, end, p->type->u.members, p->brace_level);
+			return find_struct_member(name, end, p->type->members, p->brace_level);
 		}
 		else
 		{
 			if (p->type->type != ECPGt_array)
 				mmfatal(PARSE_ERROR, "variable \"%s\" is not an array", name);
 
-			if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
+			if (p->type->element->type != ECPGt_struct && p->type->element->type != ECPGt_union)
 				mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
 
 			/* restore the name, we will need it later */
 			*next = c;
 
-			return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level);
+			return find_struct_member(name, end, p->type->element->members, p->brace_level);
 		}
 	}
 }
@@ -236,15 +236,15 @@ find_variable(const char *name)
 				if (p->type->type != ECPGt_array)
 					mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", name);
 				*next = c;
-				switch (p->type->u.element->type)
+				switch (p->type->element->type)
 				{
 					case ECPGt_array:
-						return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->counter), p->type->u.element->size), p->brace_level);
+						return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->element->element->type, p->type->element->element->size, p->type->element->element->counter), p->type->element->size), p->brace_level);
 					case ECPGt_struct:
 					case ECPGt_union:
-						return new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->type_name, p->type->u.element->struct_sizeof), p->brace_level);
+						return new_variable(name, ECPGmake_struct_type(p->type->element->members, p->type->element->type, p->type->element->type_name, p->type->element->struct_sizeof), p->brace_level);
 					default:
-						return new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->counter), p->brace_level);
+						return new_variable(name, ECPGmake_simple_type(p->type->element->type, p->type->element->size, p->type->element->counter), p->brace_level);
 				}
 			}
 		}
@@ -506,12 +506,12 @@ check_indicator(struct ECPGtype *var)
 
 		case ECPGt_struct:
 		case ECPGt_union:
-			for (p = var->u.members; p; p = p->next)
+			for (p = var->members; p; p = p->next)
 				check_indicator(p->type);
 			break;
 
 		case ECPGt_array:
-			check_indicator(var->u.element);
+			check_indicator(var->element);
 			break;
 		default:
 			mmerror(PARSE_ERROR, ET_ERROR, "indicator variable must have an integer type");
-- 
2.51.0

From dbcbc304cfeabc045b31dac69275ac55abe277ad Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 08/23] C11 anonymous unions [pgbench]

---
 src/bin/pgbench/exprparse.y | 22 ++++++++--------
 src/bin/pgbench/pgbench.c   | 52 ++++++++++++++++++-------------------
 src/bin/pgbench/pgbench.h   |  4 +--
 3 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y
index 68a37e49e45..4e291a13e95 100644
--- a/src/bin/pgbench/exprparse.y
+++ b/src/bin/pgbench/exprparse.y
@@ -170,8 +170,8 @@ make_null_constant(void)
 	PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
 
 	expr->etype = ENODE_CONSTANT;
-	expr->u.constant.type = PGBT_NULL;
-	expr->u.constant.u.ival = 0;
+	expr->constant.type = PGBT_NULL;
+	expr->constant.ival = 0;
 	return expr;
 }
 
@@ -181,8 +181,8 @@ make_integer_constant(int64 ival)
 	PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
 
 	expr->etype = ENODE_CONSTANT;
-	expr->u.constant.type = PGBT_INT;
-	expr->u.constant.u.ival = ival;
+	expr->constant.type = PGBT_INT;
+	expr->constant.ival = ival;
 	return expr;
 }
 
@@ -192,8 +192,8 @@ make_double_constant(double dval)
 	PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
 
 	expr->etype = ENODE_CONSTANT;
-	expr->u.constant.type = PGBT_DOUBLE;
-	expr->u.constant.u.dval = dval;
+	expr->constant.type = PGBT_DOUBLE;
+	expr->constant.dval = dval;
 	return expr;
 }
 
@@ -203,8 +203,8 @@ make_boolean_constant(bool bval)
 	PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
 
 	expr->etype = ENODE_CONSTANT;
-	expr->u.constant.type = PGBT_BOOLEAN;
-	expr->u.constant.u.bval = bval;
+	expr->constant.type = PGBT_BOOLEAN;
+	expr->constant.bval = bval;
 	return expr;
 }
 
@@ -214,7 +214,7 @@ make_variable(char *varname)
 	PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
 
 	expr->etype = ENODE_VARIABLE;
-	expr->u.variable.varname = varname;
+	expr->variable.varname = varname;
 	return expr;
 }
 
@@ -514,10 +514,10 @@ make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *args)
 	}
 
 	expr->etype = ENODE_FUNCTION;
-	expr->u.function.function = PGBENCH_FUNCTIONS[fnumber].tag;
+	expr->function.function = PGBENCH_FUNCTIONS[fnumber].tag;
 
 	/* only the link is used, the head/tail is not useful anymore */
-	expr->u.function.args = args != NULL ? args->head : NULL;
+	expr->function.args = args != NULL ? args->head : NULL;
 	if (args)
 		pg_free(args);
 
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 3cafd88ac53..9b4e15fab9b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1673,13 +1673,13 @@ getVariable(Variables *variables, char *name)
 		snprintf(stringform, sizeof(stringform), "NULL");
 	else if (var->value.type == PGBT_BOOLEAN)
 		snprintf(stringform, sizeof(stringform),
-				 "%s", var->value.u.bval ? "true" : "false");
+				 "%s", var->value.bval ? "true" : "false");
 	else if (var->value.type == PGBT_INT)
 		snprintf(stringform, sizeof(stringform),
-				 INT64_FORMAT, var->value.u.ival);
+				 INT64_FORMAT, var->value.ival);
 	else if (var->value.type == PGBT_DOUBLE)
 		snprintf(stringform, sizeof(stringform),
-				 "%.*g", DBL_DIG, var->value.u.dval);
+				 "%.*g", DBL_DIG, var->value.dval);
 	else						/* internal error, unexpected type */
 		Assert(0);
 	var->svalue = pg_strdup(stringform);
@@ -2032,7 +2032,7 @@ coerceToBool(PgBenchValue *pval, bool *bval)
 {
 	if (pval->type == PGBT_BOOLEAN)
 	{
-		*bval = pval->u.bval;
+		*bval = pval->bval;
 		return true;
 	}
 	else						/* NULL, INT or DOUBLE */
@@ -2055,11 +2055,11 @@ valueTruth(PgBenchValue *pval)
 		case PGBT_NULL:
 			return false;
 		case PGBT_BOOLEAN:
-			return pval->u.bval;
+			return pval->bval;
 		case PGBT_INT:
-			return pval->u.ival != 0;
+			return pval->ival != 0;
 		case PGBT_DOUBLE:
-			return pval->u.dval != 0.0;
+			return pval->dval != 0.0;
 		default:
 			/* internal error, unexpected type */
 			Assert(0);
@@ -2073,12 +2073,12 @@ coerceToInt(PgBenchValue *pval, int64 *ival)
 {
 	if (pval->type == PGBT_INT)
 	{
-		*ival = pval->u.ival;
+		*ival = pval->ival;
 		return true;
 	}
 	else if (pval->type == PGBT_DOUBLE)
 	{
-		double		dval = rint(pval->u.dval);
+		double		dval = rint(pval->dval);
 
 		if (isnan(dval) || !FLOAT8_FITS_IN_INT64(dval))
 		{
@@ -2101,12 +2101,12 @@ coerceToDouble(PgBenchValue *pval, double *dval)
 {
 	if (pval->type == PGBT_DOUBLE)
 	{
-		*dval = pval->u.dval;
+		*dval = pval->dval;
 		return true;
 	}
 	else if (pval->type == PGBT_INT)
 	{
-		*dval = (double) pval->u.ival;
+		*dval = (double) pval->ival;
 		return true;
 	}
 	else						/* BOOLEAN or NULL */
@@ -2121,7 +2121,7 @@ static void
 setNullValue(PgBenchValue *pv)
 {
 	pv->type = PGBT_NULL;
-	pv->u.ival = 0;
+	pv->ival = 0;
 }
 
 /* assign a boolean value */
@@ -2129,7 +2129,7 @@ static void
 setBoolValue(PgBenchValue *pv, bool bval)
 {
 	pv->type = PGBT_BOOLEAN;
-	pv->u.bval = bval;
+	pv->bval = bval;
 }
 
 /* assign an integer value */
@@ -2137,7 +2137,7 @@ static void
 setIntValue(PgBenchValue *pv, int64 ival)
 {
 	pv->type = PGBT_INT;
-	pv->u.ival = ival;
+	pv->ival = ival;
 }
 
 /* assign a double value */
@@ -2145,7 +2145,7 @@ static void
 setDoubleValue(PgBenchValue *pv, double dval)
 {
 	pv->type = PGBT_DOUBLE;
-	pv->u.dval = dval;
+	pv->dval = dval;
 }
 
 static bool
@@ -2525,13 +2525,13 @@ evalStandardFunc(CState *st,
 
 				if (varg->type == PGBT_INT)
 				{
-					int64		i = varg->u.ival;
+					int64		i = varg->ival;
 
 					setIntValue(retval, i < 0 ? -i : i);
 				}
 				else
 				{
-					double		d = varg->u.dval;
+					double		d = varg->dval;
 
 					Assert(varg->type == PGBT_DOUBLE);
 					setDoubleValue(retval, d < 0.0 ? -d : d);
@@ -2552,11 +2552,11 @@ evalStandardFunc(CState *st,
 				if (varg->type == PGBT_NULL)
 					fprintf(stderr, "null\n");
 				else if (varg->type == PGBT_BOOLEAN)
-					fprintf(stderr, "boolean %s\n", varg->u.bval ? "true" : "false");
+					fprintf(stderr, "boolean %s\n", varg->bval ? "true" : "false");
 				else if (varg->type == PGBT_INT)
-					fprintf(stderr, "int " INT64_FORMAT "\n", varg->u.ival);
+					fprintf(stderr, "int " INT64_FORMAT "\n", varg->ival);
 				else if (varg->type == PGBT_DOUBLE)
-					fprintf(stderr, "double %.*g\n", DBL_DIG, varg->u.dval);
+					fprintf(stderr, "double %.*g\n", DBL_DIG, varg->dval);
 				else			/* internal error, unexpected type */
 					Assert(0);
 
@@ -2779,7 +2779,7 @@ evalStandardFunc(CState *st,
 				 */
 				setBoolValue(retval,
 							 vargs[0].type == vargs[1].type &&
-							 vargs[0].u.bval == vargs[1].u.bval);
+							 vargs[0].bval == vargs[1].bval);
 				return true;
 			}
 
@@ -2862,7 +2862,7 @@ evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
 	{
 		case ENODE_CONSTANT:
 			{
-				*retval = expr->u.constant;
+				*retval = expr->constant;
 				return true;
 			}
 
@@ -2870,9 +2870,9 @@ evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
 			{
 				Variable   *var;
 
-				if ((var = lookupVariable(&st->variables, expr->u.variable.varname)) == NULL)
+				if ((var = lookupVariable(&st->variables, expr->variable.varname)) == NULL)
 				{
-					pg_log_error("undefined variable \"%s\"", expr->u.variable.varname);
+					pg_log_error("undefined variable \"%s\"", expr->variable.varname);
 					return false;
 				}
 
@@ -2885,8 +2885,8 @@ evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
 
 		case ENODE_FUNCTION:
 			return evalFunc(st,
-							expr->u.function.function,
-							expr->u.function.args,
+							expr->function.function,
+							expr->function.args,
 							retval);
 
 		default:
diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index d55d30e0ef9..7454f29bb69 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -50,7 +50,7 @@ typedef struct
 		double		dval;
 		bool		bval;
 		/* add other types here */
-	}			u;
+	};
 } PgBenchValue;
 
 /* Types of expression nodes */
@@ -122,7 +122,7 @@ struct PgBenchExpr
 			PgBenchFunction function;
 			PgBenchExprLink *args;
 		}			function;
-	}			u;
+	};
 };
 
 /* List of expression nodes */
-- 
2.51.0

From 1d7fd6be25fa1fa49680c7249893c627b0c48aed Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 09/23] C11 anonymous unions [reloptions]

---
 src/backend/access/common/reloptions.c | 34 +++++++++++++-------------
 src/include/access/reloptions.h        |  2 +-
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 0af3fea68fa..e7100d6d88f 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -578,7 +578,7 @@ static void parse_one_reloption(relopt_value *option, char *text_str,
  * relation options.
  */
 #define GET_STRING_RELOPTION_LEN(option) \
-	((option).isset ? strlen((option).values.string_val) : \
+	((option).isset ? strlen((option).string_val) : \
 	 ((relopt_string *) (option).gen)->default_len)
 
 /*
@@ -1609,7 +1609,7 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 	{
 		case RELOPT_TYPE_BOOL:
 			{
-				parsed = parse_bool(value, &option->values.bool_val);
+				parsed = parse_bool(value, &option->bool_val);
 				if (validate && !parsed)
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -1621,14 +1621,14 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 			{
 				relopt_int *optint = (relopt_int *) option->gen;
 
-				parsed = parse_int(value, &option->values.int_val, 0, NULL);
+				parsed = parse_int(value, &option->int_val, 0, NULL);
 				if (validate && !parsed)
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("invalid value for integer option \"%s\": %s",
 									option->gen->name, value)));
-				if (validate && (option->values.int_val < optint->min ||
-								 option->values.int_val > optint->max))
+				if (validate && (option->int_val < optint->min ||
+								 option->int_val > optint->max))
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("value %s out of bounds for option \"%s\"",
@@ -1641,14 +1641,14 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 			{
 				relopt_real *optreal = (relopt_real *) option->gen;
 
-				parsed = parse_real(value, &option->values.real_val, 0, NULL);
+				parsed = parse_real(value, &option->real_val, 0, NULL);
 				if (validate && !parsed)
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("invalid value for floating point option \"%s\": %s",
 									option->gen->name, value)));
-				if (validate && (option->values.real_val < optreal->min ||
-								 option->values.real_val > optreal->max))
+				if (validate && (option->real_val < optreal->min ||
+								 option->real_val > optreal->max))
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("value %s out of bounds for option \"%s\"",
@@ -1667,7 +1667,7 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 				{
 					if (pg_strcasecmp(value, elt->string_val) == 0)
 					{
-						option->values.enum_val = elt->symbol_val;
+						option->enum_val = elt->symbol_val;
 						parsed = true;
 						break;
 					}
@@ -1685,14 +1685,14 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 				 * not asked to validate, just use the default numeric value.
 				 */
 				if (!parsed)
-					option->values.enum_val = optenum->default_val;
+					option->enum_val = optenum->default_val;
 			}
 			break;
 		case RELOPT_TYPE_STRING:
 			{
 				relopt_string *optstring = (relopt_string *) option->gen;
 
-				option->values.string_val = value;
+				option->string_val = value;
 				nofree = true;
 				if (validate && optstring->validate_cb)
 					(optstring->validate_cb) (value);
@@ -1734,7 +1734,7 @@ allocateReloptStruct(Size base, relopt_value *options, int numoptions)
 
 			if (optstr->fill_cb)
 			{
-				const char *val = optval->isset ? optval->values.string_val :
+				const char *val = optval->isset ? optval->string_val :
 					optstr->default_isnull ? NULL : optstr->default_val;
 
 				size += optstr->fill_cb(val, NULL);
@@ -1795,28 +1795,28 @@ fillRelOptions(void *rdopts, Size basesize,
 				{
 					case RELOPT_TYPE_BOOL:
 						*(bool *) itempos = options[i].isset ?
-							options[i].values.bool_val :
+							options[i].bool_val :
 							((relopt_bool *) options[i].gen)->default_val;
 						break;
 					case RELOPT_TYPE_INT:
 						*(int *) itempos = options[i].isset ?
-							options[i].values.int_val :
+							options[i].int_val :
 							((relopt_int *) options[i].gen)->default_val;
 						break;
 					case RELOPT_TYPE_REAL:
 						*(double *) itempos = options[i].isset ?
-							options[i].values.real_val :
+							options[i].real_val :
 							((relopt_real *) options[i].gen)->default_val;
 						break;
 					case RELOPT_TYPE_ENUM:
 						*(int *) itempos = options[i].isset ?
-							options[i].values.enum_val :
+							options[i].enum_val :
 							((relopt_enum *) options[i].gen)->default_val;
 						break;
 					case RELOPT_TYPE_STRING:
 						optstring = (relopt_string *) options[i].gen;
 						if (options[i].isset)
-							string_val = options[i].values.string_val;
+							string_val = options[i].string_val;
 						else if (!optstring->default_isnull)
 							string_val = optstring->default_val;
 						else
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index a604a4702c3..e16b412fb4a 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -84,7 +84,7 @@ typedef struct relopt_value
 		double		real_val;
 		int			enum_val;
 		char	   *string_val; /* allocated separately */
-	}			values;
+	};
 } relopt_value;
 
 /* reloptions records for specific variable types */
-- 
2.51.0

From 328cb864b3d5d6e88a36b269246e9b8002c4dc33 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 10/23] C11 anonymous unions [gist]

---
 src/backend/access/gist/gistget.c | 28 ++++++++++++++--------------
 src/include/access/gist_private.h |  2 +-
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 387d9972345..a20d724d5ca 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -353,9 +353,9 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
 	 * parentlsn < nsn), or if the system crashed after a page split but
 	 * before the downlink was inserted into the parent.
 	 */
-	if (!XLogRecPtrIsInvalid(pageItem->data.parentlsn) &&
+	if (!XLogRecPtrIsInvalid(pageItem->parentlsn) &&
 		(GistFollowRight(page) ||
-		 pageItem->data.parentlsn < GistPageGetNSN(page)) &&
+		 pageItem->parentlsn < GistPageGetNSN(page)) &&
 		opaque->rightlink != InvalidBlockNumber /* sanity check */ )
 	{
 		/* There was a page split, follow right link to add pages */
@@ -369,7 +369,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
 		/* Create new GISTSearchItem for the right sibling index page */
 		item = palloc(SizeOfGISTSearchItem(scan->numberOfOrderBys));
 		item->blkno = opaque->rightlink;
-		item->data.parentlsn = pageItem->data.parentlsn;
+		item->parentlsn = pageItem->parentlsn;
 
 		/* Insert it into the queue using same distances as for this page */
 		memcpy(item->distances, myDistances,
@@ -493,15 +493,15 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
 			{
 				/* Creating heap-tuple GISTSearchItem */
 				item->blkno = InvalidBlockNumber;
-				item->data.heap.heapPtr = it->t_tid;
-				item->data.heap.recheck = recheck;
-				item->data.heap.recheckDistances = recheck_distances;
+				item->heap.heapPtr = it->t_tid;
+				item->heap.recheck = recheck;
+				item->heap.recheckDistances = recheck_distances;
 
 				/*
 				 * In an index-only scan, also fetch the data from the tuple.
 				 */
 				if (scan->xs_want_itup)
-					item->data.heap.recontup = gistFetchTuple(giststate, r, it);
+					item->heap.recontup = gistFetchTuple(giststate, r, it);
 			}
 			else
 			{
@@ -513,7 +513,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
 				 * only have a shared lock, so we need to get the LSN
 				 * atomically.
 				 */
-				item->data.parentlsn = BufferGetLSNAtomic(buffer);
+				item->parentlsn = BufferGetLSNAtomic(buffer);
 			}
 
 			/* Insert it into the queue using new distance data */
@@ -579,16 +579,16 @@ getNextNearest(IndexScanDesc scan)
 		if (GISTSearchItemIsHeap(*item))
 		{
 			/* found a heap item at currently minimal distance */
-			scan->xs_heaptid = item->data.heap.heapPtr;
-			scan->xs_recheck = item->data.heap.recheck;
+			scan->xs_heaptid = item->heap.heapPtr;
+			scan->xs_recheck = item->heap.recheck;
 
 			index_store_float8_orderby_distances(scan, so->orderByTypes,
 												 item->distances,
-												 item->data.heap.recheckDistances);
+												 item->heap.recheckDistances);
 
 			/* in an index-only scan, also return the reconstructed tuple. */
 			if (scan->xs_want_itup)
-				scan->xs_hitup = item->data.heap.recontup;
+				scan->xs_hitup = item->heap.recontup;
 			res = true;
 		}
 		else
@@ -635,7 +635,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
 			MemoryContextReset(so->pageDataCxt);
 
 		fakeItem.blkno = GIST_ROOT_BLKNO;
-		memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
+		memset(&fakeItem.parentlsn, 0, sizeof(GistNSN));
 		gistScanPage(scan, &fakeItem, NULL, NULL, NULL);
 	}
 
@@ -762,7 +762,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
 		MemoryContextReset(so->pageDataCxt);
 
 	fakeItem.blkno = GIST_ROOT_BLKNO;
-	memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
+	memset(&fakeItem.parentlsn, 0, sizeof(GistNSN));
 	gistScanPage(scan, &fakeItem, NULL, tbm, &ntids);
 
 	/*
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 39404ec7cdb..f7c532757a6 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -136,7 +136,7 @@ typedef struct GISTSearchItem
 		GistNSN		parentlsn;	/* parent page's LSN, if index page */
 		/* we must store parentlsn to detect whether a split occurred */
 		GISTSearchHeapItem heap;	/* heap info, if heap tuple */
-	}			data;
+	};
 
 	/* numberOfOrderBys entries */
 	IndexOrderByDistance distances[FLEXIBLE_ARRAY_MEMBER];
-- 
2.51.0

From e2c0bda7e7d6994bf2ca1d414a68e9855d623011 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 11/23] C11 anonymous unions [deparse]

---
 src/backend/commands/event_trigger.c          | 64 +++++++++----------
 src/include/tcop/deparse_utility.h            |  2 +-
 .../test_ddl_deparse/test_ddl_deparse.c       |  4 +-
 3 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index f34868da5ab..ec42d95ce5a 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -1731,8 +1731,8 @@ EventTriggerCollectSimpleCommand(ObjectAddress address,
 	command->type = SCT_Simple;
 	command->in_extension = creating_extension;
 
-	command->d.simple.address = address;
-	command->d.simple.secondaryObject = secondaryObject;
+	command->simple.address = address;
+	command->simple.secondaryObject = secondaryObject;
 	command->parsetree = copyObject(parsetree);
 
 	currentEventTriggerState->commandList = lappend(currentEventTriggerState->commandList,
@@ -1767,9 +1767,9 @@ EventTriggerAlterTableStart(Node *parsetree)
 	command->type = SCT_AlterTable;
 	command->in_extension = creating_extension;
 
-	command->d.alterTable.classId = RelationRelationId;
-	command->d.alterTable.objectId = InvalidOid;
-	command->d.alterTable.subcmds = NIL;
+	command->alterTable.classId = RelationRelationId;
+	command->alterTable.objectId = InvalidOid;
+	command->alterTable.subcmds = NIL;
 	command->parsetree = copyObject(parsetree);
 
 	command->parent = currentEventTriggerState->currentCommand;
@@ -1790,7 +1790,7 @@ EventTriggerAlterTableRelid(Oid objectId)
 		currentEventTriggerState->commandCollectionInhibited)
 		return;
 
-	currentEventTriggerState->currentCommand->d.alterTable.objectId = objectId;
+	currentEventTriggerState->currentCommand->alterTable.objectId = objectId;
 }
 
 /*
@@ -1814,7 +1814,7 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address)
 
 	Assert(IsA(subcmd, AlterTableCmd));
 	Assert(currentEventTriggerState->currentCommand != NULL);
-	Assert(OidIsValid(currentEventTriggerState->currentCommand->d.alterTable.objectId));
+	Assert(OidIsValid(currentEventTriggerState->currentCommand->alterTable.objectId));
 
 	oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt);
 
@@ -1822,8 +1822,8 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address)
 	newsub->address = address;
 	newsub->parsetree = copyObject(subcmd);
 
-	currentEventTriggerState->currentCommand->d.alterTable.subcmds =
-		lappend(currentEventTriggerState->currentCommand->d.alterTable.subcmds, newsub);
+	currentEventTriggerState->currentCommand->alterTable.subcmds =
+		lappend(currentEventTriggerState->currentCommand->alterTable.subcmds, newsub);
 
 	MemoryContextSwitchTo(oldcxt);
 }
@@ -1849,7 +1849,7 @@ EventTriggerAlterTableEnd(void)
 	parent = currentEventTriggerState->currentCommand->parent;
 
 	/* If no subcommands, don't collect */
-	if (currentEventTriggerState->currentCommand->d.alterTable.subcmds != NIL)
+	if (currentEventTriggerState->currentCommand->alterTable.subcmds != NIL)
 	{
 		MemoryContext oldcxt;
 
@@ -1904,7 +1904,7 @@ EventTriggerCollectGrant(InternalGrant *istmt)
 	command = palloc(sizeof(CollectedCommand));
 	command->type = SCT_Grant;
 	command->in_extension = creating_extension;
-	command->d.grant.istmt = icopy;
+	command->grant.istmt = icopy;
 	command->parsetree = NULL;
 
 	currentEventTriggerState->commandList =
@@ -1935,10 +1935,10 @@ EventTriggerCollectAlterOpFam(AlterOpFamilyStmt *stmt, Oid opfamoid,
 	command = palloc(sizeof(CollectedCommand));
 	command->type = SCT_AlterOpFamily;
 	command->in_extension = creating_extension;
-	ObjectAddressSet(command->d.opfam.address,
+	ObjectAddressSet(command->opfam.address,
 					 OperatorFamilyRelationId, opfamoid);
-	command->d.opfam.operators = operators;
-	command->d.opfam.procedures = procedures;
+	command->opfam.operators = operators;
+	command->opfam.procedures = procedures;
 	command->parsetree = (Node *) copyObject(stmt);
 
 	currentEventTriggerState->commandList =
@@ -1968,10 +1968,10 @@ EventTriggerCollectCreateOpClass(CreateOpClassStmt *stmt, Oid opcoid,
 	command = palloc0(sizeof(CollectedCommand));
 	command->type = SCT_CreateOpClass;
 	command->in_extension = creating_extension;
-	ObjectAddressSet(command->d.createopc.address,
+	ObjectAddressSet(command->createopc.address,
 					 OperatorClassRelationId, opcoid);
-	command->d.createopc.operators = operators;
-	command->d.createopc.procedures = procedures;
+	command->createopc.operators = operators;
+	command->createopc.procedures = procedures;
 	command->parsetree = (Node *) copyObject(stmt);
 
 	currentEventTriggerState->commandList =
@@ -2002,11 +2002,11 @@ EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId,
 	command = palloc0(sizeof(CollectedCommand));
 	command->type = SCT_AlterTSConfig;
 	command->in_extension = creating_extension;
-	ObjectAddressSet(command->d.atscfg.address,
+	ObjectAddressSet(command->atscfg.address,
 					 TSConfigRelationId, cfgId);
-	command->d.atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
-	memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
-	command->d.atscfg.ndicts = ndicts;
+	command->atscfg.dictIds = palloc(sizeof(Oid) * ndicts);
+	memcpy(command->atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
+	command->atscfg.ndicts = ndicts;
 	command->parsetree = (Node *) copyObject(stmt);
 
 	currentEventTriggerState->commandList =
@@ -2035,7 +2035,7 @@ EventTriggerCollectAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt)
 
 	command = palloc0(sizeof(CollectedCommand));
 	command->type = SCT_AlterDefaultPrivileges;
-	command->d.defprivs.objtype = stmt->action->objtype;
+	command->defprivs.objtype = stmt->action->objtype;
 	command->in_extension = creating_extension;
 	command->parsetree = (Node *) copyObject(stmt);
 
@@ -2085,7 +2085,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 		 * state anyway.
 		 */
 		if (cmd->type == SCT_Simple &&
-			!OidIsValid(cmd->d.simple.address.objectId))
+			!OidIsValid(cmd->simple.address.objectId))
 			continue;
 
 		switch (cmd->type)
@@ -2101,17 +2101,17 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 					char	   *schema = NULL;
 
 					if (cmd->type == SCT_Simple)
-						addr = cmd->d.simple.address;
+						addr = cmd->simple.address;
 					else if (cmd->type == SCT_AlterTable)
 						ObjectAddressSet(addr,
-										 cmd->d.alterTable.classId,
-										 cmd->d.alterTable.objectId);
+										 cmd->alterTable.classId,
+										 cmd->alterTable.objectId);
 					else if (cmd->type == SCT_AlterOpFamily)
-						addr = cmd->d.opfam.address;
+						addr = cmd->opfam.address;
 					else if (cmd->type == SCT_CreateOpClass)
-						addr = cmd->d.createopc.address;
+						addr = cmd->createopc.address;
 					else if (cmd->type == SCT_AlterTSConfig)
-						addr = cmd->d.atscfg.address;
+						addr = cmd->atscfg.address;
 
 					/*
 					 * If an object was dropped in the same command we may end
@@ -2199,7 +2199,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 				/* command tag */
 				values[i++] = CStringGetTextDatum(CreateCommandName(cmd->parsetree));
 				/* object_type */
-				values[i++] = CStringGetTextDatum(stringify_adefprivs_objtype(cmd->d.defprivs.objtype));
+				values[i++] = CStringGetTextDatum(stringify_adefprivs_objtype(cmd->defprivs.objtype));
 				/* schema */
 				nulls[i++] = true;
 				/* identity */
@@ -2218,10 +2218,10 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 				/* objsubid */
 				nulls[i++] = true;
 				/* command tag */
-				values[i++] = CStringGetTextDatum(cmd->d.grant.istmt->is_grant ?
+				values[i++] = CStringGetTextDatum(cmd->grant.istmt->is_grant ?
 												  "GRANT" : "REVOKE");
 				/* object_type */
-				values[i++] = CStringGetTextDatum(stringify_grant_objtype(cmd->d.grant.istmt->objtype));
+				values[i++] = CStringGetTextDatum(stringify_grant_objtype(cmd->grant.istmt->objtype));
 				/* schema */
 				nulls[i++] = true;
 				/* identity */
diff --git a/src/include/tcop/deparse_utility.h b/src/include/tcop/deparse_utility.h
index 36510451d83..4ed83315bd9 100644
--- a/src/include/tcop/deparse_utility.h
+++ b/src/include/tcop/deparse_utility.h
@@ -100,7 +100,7 @@ typedef struct CollectedCommand
 		{
 			ObjectType	objtype;
 		}			defprivs;
-	}			d;
+	};
 
 	struct CollectedCommand *parent;	/* when nested */
 } CollectedCommand;
diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
index 193669f2bc1..d002121ada3 100644
--- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
+++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
@@ -94,10 +94,10 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
 
 	InitMaterializedSRF(fcinfo, 0);
 
-	if (cmd->d.alterTable.subcmds == NIL)
+	if (cmd->alterTable.subcmds == NIL)
 		elog(ERROR, "empty alter table subcommand list");
 
-	foreach(cell, cmd->d.alterTable.subcmds)
+	foreach(cell, cmd->alterTable.subcmds)
 	{
 		CollectedATSubcmd *sub = lfirst(cell);
 		AlterTableCmd *subcmd = castNode(AlterTableCmd, sub->parsetree);
-- 
2.51.0

From 575c905437bbf22c020768396ed1a91788344c59 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 12/23] C11 anonymous unions [tsearch ParsedWord]

---
 src/backend/tsearch/to_tsany.c | 60 +++++++++++++++++-----------------
 src/backend/tsearch/ts_parse.c |  2 +-
 src/include/tsearch/ts_utils.h |  2 +-
 3 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c
index 4dfcc2cd3bd..49a4da46908 100644
--- a/src/backend/tsearch/to_tsany.c
+++ b/src/backend/tsearch/to_tsany.c
@@ -64,10 +64,10 @@ compareWORD(const void *a, const void *b)
 
 	if (res == 0)
 	{
-		if (((const ParsedWord *) a)->pos.pos == ((const ParsedWord *) b)->pos.pos)
+		if (((const ParsedWord *) a)->pos == ((const ParsedWord *) b)->pos)
 			return 0;
 
-		res = (((const ParsedWord *) a)->pos.pos > ((const ParsedWord *) b)->pos.pos) ? 1 : -1;
+		res = (((const ParsedWord *) a)->pos > ((const ParsedWord *) b)->pos) ? 1 : -1;
 	}
 
 	return res;
@@ -82,11 +82,11 @@ uniqueWORD(ParsedWord *a, int32 l)
 
 	if (l == 1)
 	{
-		tmppos = LIMITPOS(a->pos.pos);
+		tmppos = LIMITPOS(a->pos);
 		a->alen = 2;
-		a->pos.apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
-		a->pos.apos[0] = 1;
-		a->pos.apos[1] = tmppos;
+		a->apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
+		a->apos[0] = 1;
+		a->apos[1] = tmppos;
 		return l;
 	}
 
@@ -101,11 +101,11 @@ uniqueWORD(ParsedWord *a, int32 l)
 	/*
 	 * Initialize first word and its first position
 	 */
-	tmppos = LIMITPOS(a->pos.pos);
+	tmppos = LIMITPOS(a->pos);
 	a->alen = 2;
-	a->pos.apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
-	a->pos.apos[0] = 1;
-	a->pos.apos[1] = tmppos;
+	a->apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
+	a->apos[0] = 1;
+	a->apos[1] = tmppos;
 
 	/*
 	 * Summarize position information for each word
@@ -121,11 +121,11 @@ uniqueWORD(ParsedWord *a, int32 l)
 			res++;
 			res->len = ptr->len;
 			res->word = ptr->word;
-			tmppos = LIMITPOS(ptr->pos.pos);
+			tmppos = LIMITPOS(ptr->pos);
 			res->alen = 2;
-			res->pos.apos = (uint16 *) palloc(sizeof(uint16) * res->alen);
-			res->pos.apos[0] = 1;
-			res->pos.apos[1] = tmppos;
+			res->apos = (uint16 *) palloc(sizeof(uint16) * res->alen);
+			res->apos[0] = 1;
+			res->apos[1] = tmppos;
 		}
 		else
 		{
@@ -135,18 +135,18 @@ uniqueWORD(ParsedWord *a, int32 l)
 			 * value for position and uniqueness of position
 			 */
 			pfree(ptr->word);
-			if (res->pos.apos[0] < MAXNUMPOS - 1 && res->pos.apos[res->pos.apos[0]] != MAXENTRYPOS - 1 &&
-				res->pos.apos[res->pos.apos[0]] != LIMITPOS(ptr->pos.pos))
+			if (res->apos[0] < MAXNUMPOS - 1 && res->apos[res->apos[0]] != MAXENTRYPOS - 1 &&
+				res->apos[res->apos[0]] != LIMITPOS(ptr->pos))
 			{
-				if (res->pos.apos[0] + 1 >= res->alen)
+				if (res->apos[0] + 1 >= res->alen)
 				{
 					res->alen *= 2;
-					res->pos.apos = (uint16 *) repalloc(res->pos.apos, sizeof(uint16) * res->alen);
+					res->apos = (uint16 *) repalloc(res->apos, sizeof(uint16) * res->alen);
 				}
-				if (res->pos.apos[0] == 0 || res->pos.apos[res->pos.apos[0]] != LIMITPOS(ptr->pos.pos))
+				if (res->apos[0] == 0 || res->apos[res->apos[0]] != LIMITPOS(ptr->pos))
 				{
-					res->pos.apos[res->pos.apos[0] + 1] = LIMITPOS(ptr->pos.pos);
-					res->pos.apos[0]++;
+					res->apos[res->apos[0] + 1] = LIMITPOS(ptr->pos);
+					res->apos[0]++;
 				}
 			}
 		}
@@ -184,7 +184,7 @@ make_tsvector(ParsedText *prs)
 		if (prs->words[i].alen)
 		{
 			lenstr = SHORTALIGN(lenstr);
-			lenstr += sizeof(uint16) + prs->words[i].pos.apos[0] * sizeof(WordEntryPos);
+			lenstr += sizeof(uint16) + prs->words[i].apos[0] * sizeof(WordEntryPos);
 		}
 	}
 
@@ -210,7 +210,7 @@ make_tsvector(ParsedText *prs)
 		pfree(prs->words[i].word);
 		if (prs->words[i].alen)
 		{
-			int			k = prs->words[i].pos.apos[0];
+			int			k = prs->words[i].apos[0];
 			WordEntryPos *wptr;
 
 			if (k > 0xFFFF)
@@ -223,10 +223,10 @@ make_tsvector(ParsedText *prs)
 			for (j = 0; j < k; j++)
 			{
 				WEP_SETWEIGHT(wptr[j], 0);
-				WEP_SETPOS(wptr[j], prs->words[i].pos.apos[j + 1]);
+				WEP_SETPOS(wptr[j], prs->words[i].apos[j + 1]);
 			}
 			stroff += sizeof(uint16) + k * sizeof(WordEntryPos);
-			pfree(prs->words[i].pos.apos);
+			pfree(prs->words[i].apos);
 		}
 		else
 			ptr->haspos = 0;
@@ -515,9 +515,9 @@ pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval,
 			 * Were any stop words removed? If so, fill empty positions with
 			 * placeholders linked by an appropriate operator.
 			 */
-			if (pos > 0 && pos + 1 < prs.words[count].pos.pos)
+			if (pos > 0 && pos + 1 < prs.words[count].pos)
 			{
-				while (pos + 1 < prs.words[count].pos.pos)
+				while (pos + 1 < prs.words[count].pos)
 				{
 					/* put placeholders for each missing stop word */
 					pushStop(state);
@@ -529,18 +529,18 @@ pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval,
 			}
 
 			/* save current word's position */
-			pos = prs.words[count].pos.pos;
+			pos = prs.words[count].pos;
 
 			/* Go through all variants obtained from this token */
 			cntvar = 0;
-			while (count < prs.curwords && pos == prs.words[count].pos.pos)
+			while (count < prs.curwords && pos == prs.words[count].pos)
 			{
 				variant = prs.words[count].nvariant;
 
 				/* Push all words belonging to the same variant */
 				cnt = 0;
 				while (count < prs.curwords &&
-					   pos == prs.words[count].pos.pos &&
+					   pos == prs.words[count].pos &&
 					   variant == prs.words[count].nvariant)
 				{
 					pushValue(state,
diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c
index cba421892bf..aed007679e2 100644
--- a/src/backend/tsearch/ts_parse.c
+++ b/src/backend/tsearch/ts_parse.c
@@ -420,7 +420,7 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen)
 				prs->words[prs->curwords].nvariant = ptr->nvariant;
 				prs->words[prs->curwords].flags = ptr->flags & TSL_PREFIX;
 				prs->words[prs->curwords].alen = 0;
-				prs->words[prs->curwords].pos.pos = LIMITPOS(prs->pos);
+				prs->words[prs->curwords].pos = LIMITPOS(prs->pos);
 				ptr++;
 				prs->curwords++;
 			}
diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h
index 7debc85ed80..9ec665be99e 100644
--- a/src/include/tsearch/ts_utils.h
+++ b/src/include/tsearch/ts_utils.h
@@ -95,7 +95,7 @@ typedef struct
 		 * array.  We do not allow more than MAXNUMPOS array elements.
 		 */
 		uint16	   *apos;
-	}			pos;
+	};
 	char	   *word;
 } ParsedWord;
 
-- 
2.51.0

From 0f629f4a2e1191ddf94f9351363909d63b68351d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 13/23] C11 anonymous unions [tsearch spell]

---
 src/backend/tsearch/spell.c       | 70 +++++++++++++++----------------
 src/include/tsearch/dicts/spell.h | 10 ++---
 2 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index 146801885d7..ddad17796e4 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -203,8 +203,8 @@ cmpspell(const void *s1, const void *s2)
 static int
 cmpspellaffix(const void *s1, const void *s2)
 {
-	return strcmp((*(SPELL *const *) s1)->p.flag,
-				  (*(SPELL *const *) s2)->p.flag);
+	return strcmp((*(SPELL *const *) s1)->flag,
+				  (*(SPELL *const *) s2)->flag);
 }
 
 static int
@@ -217,13 +217,13 @@ cmpcmdflag(const void *f1, const void *f2)
 
 	if (fv1->flagMode == FM_NUM)
 	{
-		if (fv1->flag.i == fv2->flag.i)
+		if (fv1->flagNum == fv2->flagNum)
 			return 0;
 
-		return (fv1->flag.i > fv2->flag.i) ? 1 : -1;
+		return (fv1->flagNum > fv2->flagNum) ? 1 : -1;
 	}
 
-	return strcmp(fv1->flag.s, fv2->flag.s);
+	return strcmp(fv1->flagName, fv2->flagName);
 }
 
 static char *
@@ -502,7 +502,7 @@ NIAddSpell(IspellDict *Conf, const char *word, const char *flag)
 	}
 	Conf->Spell[Conf->nspell] = (SPELL *) tmpalloc(SPELLHDRSZ + strlen(word) + 1);
 	strcpy(Conf->Spell[Conf->nspell]->word, word);
-	Conf->Spell[Conf->nspell]->p.flag = (*flag != '\0')
+	Conf->Spell[Conf->nspell]->flag = (*flag != '\0')
 		? cpstrdup(Conf, flag) : VoidString;
 	Conf->nspell++;
 }
@@ -708,7 +708,7 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
 	{
 		Affix->issimple = 0;
 		Affix->isregis = 1;
-		RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX),
+		RS_compile(&(Affix->regis), (type == FF_SUFFIX),
 				   *mask ? mask : VoidString);
 	}
 	/* This affix rule will use regex_t to search word ending */
@@ -737,15 +737,15 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
 		 * allocated in the dictionary's memory context, and will be freed
 		 * automatically when it is destroyed.
 		 */
-		Affix->reg.pregex = palloc(sizeof(regex_t));
-		err = pg_regcomp(Affix->reg.pregex, wmask, wmasklen,
+		Affix->pregex = palloc(sizeof(regex_t));
+		err = pg_regcomp(Affix->pregex, wmask, wmasklen,
 						 REG_ADVANCED | REG_NOSUB,
 						 DEFAULT_COLLATION_OID);
 		if (err)
 		{
 			char		errstr[100];
 
-			pg_regerror(err, Affix->reg.pregex, errstr, sizeof(errstr));
+			pg_regerror(err, Affix->pregex, errstr, sizeof(errstr));
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
 					 errmsg("invalid regular expression: %s", errstr)));
@@ -1049,10 +1049,10 @@ setCompoundAffixFlagValue(IspellDict *Conf, CompoundAffixFlag *entry,
 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
 					 errmsg("affix flag \"%s\" is out of range", s)));
 
-		entry->flag.i = i;
+		entry->flagNum = i;
 	}
 	else
-		entry->flag.s = cpstrdup(Conf, s);
+		entry->flagName = cpstrdup(Conf, s);
 
 	entry->flagMode = Conf->flagMode;
 	entry->value = val;
@@ -1651,7 +1651,7 @@ mkSPNode(IspellDict *Conf, int low, int high, int level)
 	int			lownew = low;
 
 	for (i = low; i < high; i++)
-		if (Conf->Spell[i]->p.d.len > level && lastchar != Conf->Spell[i]->word[level])
+		if (Conf->Spell[i]->d.len > level && lastchar != Conf->Spell[i]->word[level])
 		{
 			nchar++;
 			lastchar = Conf->Spell[i]->word[level];
@@ -1666,7 +1666,7 @@ mkSPNode(IspellDict *Conf, int low, int high, int level)
 
 	lastchar = '\0';
 	for (i = low; i < high; i++)
-		if (Conf->Spell[i]->p.d.len > level)
+		if (Conf->Spell[i]->d.len > level)
 		{
 			if (lastchar != Conf->Spell[i]->word[level])
 			{
@@ -1680,11 +1680,11 @@ mkSPNode(IspellDict *Conf, int low, int high, int level)
 				lastchar = Conf->Spell[i]->word[level];
 			}
 			data->val = ((uint8 *) (Conf->Spell[i]->word))[level];
-			if (Conf->Spell[i]->p.d.len == level + 1)
+			if (Conf->Spell[i]->d.len == level + 1)
 			{
 				bool		clearCompoundOnly = false;
 
-				if (data->isword && data->affix != Conf->Spell[i]->p.d.affix)
+				if (data->isword && data->affix != Conf->Spell[i]->d.affix)
 				{
 					/*
 					 * MergeAffix called a few times. If one of word is
@@ -1693,12 +1693,12 @@ mkSPNode(IspellDict *Conf, int low, int high, int level)
 					 */
 
 					clearCompoundOnly = (FF_COMPOUNDONLY & data->compoundflag
-										 & makeCompoundFlags(Conf, Conf->Spell[i]->p.d.affix))
+										 & makeCompoundFlags(Conf, Conf->Spell[i]->d.affix))
 						? false : true;
-					data->affix = MergeAffix(Conf, data->affix, Conf->Spell[i]->p.d.affix);
+					data->affix = MergeAffix(Conf, data->affix, Conf->Spell[i]->d.affix);
 				}
 				else
-					data->affix = Conf->Spell[i]->p.d.affix;
+					data->affix = Conf->Spell[i]->d.affix;
 				data->isword = 1;
 
 				data->compoundflag = makeCompoundFlags(Conf, data->affix);
@@ -1741,37 +1741,37 @@ NISortDictionary(IspellDict *Conf)
 		{
 			char	   *end;
 
-			if (*Conf->Spell[i]->p.flag != '\0')
+			if (*Conf->Spell[i]->flag != '\0')
 			{
 				errno = 0;
-				curaffix = strtol(Conf->Spell[i]->p.flag, &end, 10);
-				if (Conf->Spell[i]->p.flag == end || errno == ERANGE)
+				curaffix = strtol(Conf->Spell[i]->flag, &end, 10);
+				if (Conf->Spell[i]->flag == end || errno == ERANGE)
 					ereport(ERROR,
 							(errcode(ERRCODE_CONFIG_FILE_ERROR),
 							 errmsg("invalid affix alias \"%s\"",
-									Conf->Spell[i]->p.flag)));
+									Conf->Spell[i]->flag)));
 				if (curaffix < 0 || curaffix >= Conf->nAffixData)
 					ereport(ERROR,
 							(errcode(ERRCODE_CONFIG_FILE_ERROR),
 							 errmsg("invalid affix alias \"%s\"",
-									Conf->Spell[i]->p.flag)));
+									Conf->Spell[i]->flag)));
 				if (*end != '\0' && !isdigit((unsigned char) *end) && !isspace((unsigned char) *end))
 					ereport(ERROR,
 							(errcode(ERRCODE_CONFIG_FILE_ERROR),
 							 errmsg("invalid affix alias \"%s\"",
-									Conf->Spell[i]->p.flag)));
+									Conf->Spell[i]->flag)));
 			}
 			else
 			{
 				/*
-				 * If Conf->Spell[i]->p.flag is empty, then get empty value of
+				 * If Conf->Spell[i]->flag is empty, then get empty value of
 				 * Conf->AffixData (0 index).
 				 */
 				curaffix = 0;
 			}
 
-			Conf->Spell[i]->p.d.affix = curaffix;
-			Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
+			Conf->Spell[i]->d.affix = curaffix;
+			Conf->Spell[i]->d.len = strlen(Conf->Spell[i]->word);
 		}
 	}
 	/* Otherwise fill Conf->AffixData here */
@@ -1785,7 +1785,7 @@ NISortDictionary(IspellDict *Conf)
 		for (i = 0; i < Conf->nspell; i++)
 		{
 			if (i == 0 ||
-				strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag) != 0)
+				strcmp(Conf->Spell[i]->flag, Conf->Spell[i - 1]->flag) != 0)
 				naffix++;
 		}
 
@@ -1800,16 +1800,16 @@ NISortDictionary(IspellDict *Conf)
 		for (i = 0; i < Conf->nspell; i++)
 		{
 			if (i == 0 ||
-				strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix]) != 0)
+				strcmp(Conf->Spell[i]->flag, Conf->AffixData[curaffix]) != 0)
 			{
 				curaffix++;
 				Assert(curaffix < naffix);
 				Conf->AffixData[curaffix] = cpstrdup(Conf,
-													 Conf->Spell[i]->p.flag);
+													 Conf->Spell[i]->flag);
 			}
 
-			Conf->Spell[i]->p.d.affix = curaffix;
-			Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
+			Conf->Spell[i]->d.affix = curaffix;
+			Conf->Spell[i]->d.len = strlen(Conf->Spell[i]->word);
 		}
 
 		Conf->lenAffixData = Conf->nAffixData = naffix;
@@ -2136,7 +2136,7 @@ CheckAffix(const char *word, size_t len, AFFIX *Affix, int flagflags, char *neww
 		return newword;
 	else if (Affix->isregis)
 	{
-		if (RS_execute(&(Affix->reg.regis), newword))
+		if (RS_execute(&(Affix->regis), newword))
 			return newword;
 	}
 	else
@@ -2150,7 +2150,7 @@ CheckAffix(const char *word, size_t len, AFFIX *Affix, int flagflags, char *neww
 		data = (pg_wchar *) palloc((newword_len + 1) * sizeof(pg_wchar));
 		data_len = pg_mb2wchar_with_len(newword, data, newword_len);
 
-		if (pg_regexec(Affix->reg.pregex, data, data_len,
+		if (pg_regexec(Affix->pregex, data, data_len,
 					   0, NULL, 0, NULL, 0) == REG_OKAY)
 		{
 			pfree(data);
diff --git a/src/include/tsearch/dicts/spell.h b/src/include/tsearch/dicts/spell.h
index 919b7df6370..7ce7086e6df 100644
--- a/src/include/tsearch/dicts/spell.h
+++ b/src/include/tsearch/dicts/spell.h
@@ -75,7 +75,7 @@ typedef struct spell_struct
 			/* Length of the word */
 			int			len;
 		}			d;
-	}			p;
+	};
 	char		word[FLEXIBLE_ARRAY_MEMBER];
 } SPELL;
 
@@ -104,7 +104,7 @@ typedef struct aff_struct
 		 */
 		regex_t    *pregex;
 		Regis		regis;
-	}			reg;
+	};
 } AFFIX;
 
 /*
@@ -170,10 +170,10 @@ typedef struct CompoundAffixFlag
 	union
 	{
 		/* Flag name if flagMode is FM_CHAR or FM_LONG */
-		const char *s;
+		const char *flagName;
 		/* Flag name if flagMode is FM_NUM */
-		uint32		i;
-	}			flag;
+		uint32		flagNum;
+	};
 	/* we don't have a bsearch_arg version, so, copy FlagMode */
 	FlagMode	flagMode;
 	uint32		value;
-- 
2.51.0

From 1510a338ed0a7648d388bec4a2e9abcb75bcec45 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 14/23] C11 anonymous unions [predicate]

---
 src/backend/storage/lmgr/predicate.c      | 8 ++++----
 src/include/storage/predicate_internals.h | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index c1d8511ad17..732061d1281 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -4796,8 +4796,8 @@ AtPrepare_PredicateLocks(void)
 	dlist_iter	iter;
 
 	sxact = MySerializableXact;
-	xactRecord = &(record.data.xactRecord);
-	lockRecord = &(record.data.lockRecord);
+	xactRecord = &(record.xactRecord);
+	lockRecord = &(record.lockRecord);
 
 	if (MySerializableXact == InvalidSerializableXact)
 		return;
@@ -4928,7 +4928,7 @@ predicatelock_twophase_recover(FullTransactionId fxid, uint16 info,
 		SERIALIZABLEXIDTAG sxidtag;
 		bool		found;
 
-		xactRecord = (TwoPhasePredicateXactRecord *) &record->data.xactRecord;
+		xactRecord = (TwoPhasePredicateXactRecord *) &record->xactRecord;
 
 		LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
 		sxact = CreatePredXact();
@@ -5021,7 +5021,7 @@ predicatelock_twophase_recover(FullTransactionId fxid, uint16 info,
 		SERIALIZABLEXIDTAG sxidtag;
 		uint32		targettaghash;
 
-		lockRecord = (TwoPhasePredicateLockRecord *) &record->data.lockRecord;
+		lockRecord = (TwoPhasePredicateLockRecord *) &record->lockRecord;
 		targettaghash = PredicateLockTargetTagHashCode(&lockRecord->target);
 
 		LWLockAcquire(SerializableXactHashLock, LW_SHARED);
diff --git a/src/include/storage/predicate_internals.h b/src/include/storage/predicate_internals.h
index 5c3ea37f250..cd75cbff441 100644
--- a/src/include/storage/predicate_internals.h
+++ b/src/include/storage/predicate_internals.h
@@ -458,7 +458,7 @@ typedef struct TwoPhasePredicateRecord
 	{
 		TwoPhasePredicateXactRecord xactRecord;
 		TwoPhasePredicateLockRecord lockRecord;
-	}			data;
+	};
 } TwoPhasePredicateRecord;
 
 /*
-- 
2.51.0

From 18f4452e98d2d6f2467d4da759d113a21526edf3 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 15/23] C11 anonymous unions [cryptohash]

---
 src/common/cryptohash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/common/cryptohash.c b/src/common/cryptohash.c
index 533e4aaea36..2390d3ad3da 100644
--- a/src/common/cryptohash.c
+++ b/src/common/cryptohash.c
@@ -61,7 +61,7 @@ struct pg_cryptohash_ctx
 		pg_sha256_ctx sha256;
 		pg_sha384_ctx sha384;
 		pg_sha512_ctx sha512;
-	}			data;
+	};
 };
 
 /*
-- 
2.51.0

From a027beef853213ebbbe5344c7bd5bc791ab678ac Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 16/23] C11 anonymous unions [freepage]

---
 src/backend/utils/mmgr/freepage.c | 144 +++++++++++++++---------------
 1 file changed, 72 insertions(+), 72 deletions(-)

diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c
index 52fa78dc586..a112807cbdd 100644
--- a/src/backend/utils/mmgr/freepage.c
+++ b/src/backend/utils/mmgr/freepage.c
@@ -112,7 +112,7 @@ struct FreePageBtree
 	{
 		FreePageBtreeInternalKey internal_key[FPM_ITEMS_PER_INTERNAL_PAGE];
 		FreePageBtreeLeafKey leaf_key[FPM_ITEMS_PER_LEAF_PAGE];
-	}			u;
+	};
 };
 
 /* Results of a btree search */
@@ -265,7 +265,7 @@ sum_free_pages_recurse(FreePageManager *fpm, FreePageBtree *btp, Size *sum)
 		{
 			FreePageBtree *child;
 
-			child = relptr_access(base, btp->u.internal_key[index].child);
+			child = relptr_access(base, btp->internal_key[index].child);
 			sum_free_pages_recurse(fpm, child, sum);
 		}
 	}
@@ -510,13 +510,13 @@ FreePageBtreeAdjustAncestorKeys(FreePageManager *fpm, FreePageBtree *btp)
 	if (btp->hdr.magic == FREE_PAGE_LEAF_MAGIC)
 	{
 		Assert(btp->hdr.nused <= FPM_ITEMS_PER_LEAF_PAGE);
-		first_page = btp->u.leaf_key[0].first_page;
+		first_page = btp->leaf_key[0].first_page;
 	}
 	else
 	{
 		Assert(btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
 		Assert(btp->hdr.nused <= FPM_ITEMS_PER_INTERNAL_PAGE);
-		first_page = btp->u.internal_key[0].first_page;
+		first_page = btp->internal_key[0].first_page;
 	}
 	child = btp;
 
@@ -540,7 +540,7 @@ FreePageBtreeAdjustAncestorKeys(FreePageManager *fpm, FreePageBtree *btp)
 		{
 			FreePageBtree *check;
 
-			check = relptr_access(base, parent->u.internal_key[s].child);
+			check = relptr_access(base, parent->internal_key[s].child);
 			if (check != child)
 			{
 				Assert(s > 0);
@@ -553,14 +553,14 @@ FreePageBtreeAdjustAncestorKeys(FreePageManager *fpm, FreePageBtree *btp)
 		{
 			FreePageBtree *check;
 
-			check = relptr_access(base, parent->u.internal_key[s].child);
+			check = relptr_access(base, parent->internal_key[s].child);
 			Assert(s < parent->hdr.nused);
 			Assert(child == check);
 		}
 #endif
 
 		/* Update the parent key. */
-		parent->u.internal_key[s].first_page = first_page;
+		parent->internal_key[s].first_page = first_page;
 
 		/*
 		 * If this is the first key in the parent, go up another level; else
@@ -597,8 +597,8 @@ FreePageBtreeCleanup(FreePageManager *fpm)
 			{
 				/* If root is a leaf, convert only entry to singleton range. */
 				relptr_store(base, fpm->btree_root, (FreePageBtree *) NULL);
-				fpm->singleton_first_page = root->u.leaf_key[0].first_page;
-				fpm->singleton_npages = root->u.leaf_key[0].npages;
+				fpm->singleton_first_page = root->leaf_key[0].first_page;
+				fpm->singleton_npages = root->leaf_key[0].npages;
 			}
 			else
 			{
@@ -606,7 +606,7 @@ FreePageBtreeCleanup(FreePageManager *fpm)
 
 				/* If root is an internal page, make only child the root. */
 				Assert(root->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
-				relptr_copy(fpm->btree_root, root->u.internal_key[0].child);
+				relptr_copy(fpm->btree_root, root->internal_key[0].child);
 				newroot = relptr_access(base, fpm->btree_root);
 				relptr_store(base, newroot->hdr.parent, (FreePageBtree *) NULL);
 			}
@@ -618,9 +618,9 @@ FreePageBtreeCleanup(FreePageManager *fpm)
 			Size		end_of_first;
 			Size		start_of_second;
 
-			end_of_first = root->u.leaf_key[0].first_page +
-				root->u.leaf_key[0].npages;
-			start_of_second = root->u.leaf_key[1].first_page;
+			end_of_first = root->leaf_key[0].first_page +
+				root->leaf_key[0].npages;
+			start_of_second = root->leaf_key[1].first_page;
 
 			if (end_of_first + 1 == start_of_second)
 			{
@@ -628,11 +628,11 @@ FreePageBtreeCleanup(FreePageManager *fpm)
 
 				if (end_of_first == root_page)
 				{
-					FreePagePopSpanLeader(fpm, root->u.leaf_key[0].first_page);
-					FreePagePopSpanLeader(fpm, root->u.leaf_key[1].first_page);
-					fpm->singleton_first_page = root->u.leaf_key[0].first_page;
-					fpm->singleton_npages = root->u.leaf_key[0].npages +
-						root->u.leaf_key[1].npages + 1;
+					FreePagePopSpanLeader(fpm, root->leaf_key[0].first_page);
+					FreePagePopSpanLeader(fpm, root->leaf_key[1].first_page);
+					fpm->singleton_first_page = root->leaf_key[0].first_page;
+					fpm->singleton_npages = root->leaf_key[0].npages +
+						root->leaf_key[1].npages + 1;
 					fpm->btree_depth = 0;
 					relptr_store(base, fpm->btree_root,
 								 (FreePageBtree *) NULL);
@@ -725,13 +725,13 @@ FreePageBtreeConsolidate(FreePageManager *fpm, FreePageBtree *btp)
 	{
 		if (btp->hdr.magic == FREE_PAGE_LEAF_MAGIC)
 		{
-			memcpy(&btp->u.leaf_key[btp->hdr.nused], &np->u.leaf_key[0],
+			memcpy(&btp->leaf_key[btp->hdr.nused], &np->leaf_key[0],
 				   sizeof(FreePageBtreeLeafKey) * np->hdr.nused);
 			btp->hdr.nused += np->hdr.nused;
 		}
 		else
 		{
-			memcpy(&btp->u.internal_key[btp->hdr.nused], &np->u.internal_key[0],
+			memcpy(&btp->internal_key[btp->hdr.nused], &np->internal_key[0],
 				   sizeof(FreePageBtreeInternalKey) * np->hdr.nused);
 			btp->hdr.nused += np->hdr.nused;
 			FreePageBtreeUpdateParentPointers(base, btp);
@@ -750,13 +750,13 @@ FreePageBtreeConsolidate(FreePageManager *fpm, FreePageBtree *btp)
 	{
 		if (btp->hdr.magic == FREE_PAGE_LEAF_MAGIC)
 		{
-			memcpy(&np->u.leaf_key[np->hdr.nused], &btp->u.leaf_key[0],
+			memcpy(&np->leaf_key[np->hdr.nused], &btp->leaf_key[0],
 				   sizeof(FreePageBtreeLeafKey) * btp->hdr.nused);
 			np->hdr.nused += btp->hdr.nused;
 		}
 		else
 		{
-			memcpy(&np->u.internal_key[np->hdr.nused], &btp->u.internal_key[0],
+			memcpy(&np->internal_key[np->hdr.nused], &btp->internal_key[0],
 				   sizeof(FreePageBtreeInternalKey) * btp->hdr.nused);
 			np->hdr.nused += btp->hdr.nused;
 			FreePageBtreeUpdateParentPointers(base, np);
@@ -791,8 +791,8 @@ FreePageBtreeFindLeftSibling(char *base, FreePageBtree *btp)
 		index = FreePageBtreeSearchInternal(p, first_page);
 		if (index > 0)
 		{
-			Assert(p->u.internal_key[index].first_page == first_page);
-			p = relptr_access(base, p->u.internal_key[index - 1].child);
+			Assert(p->internal_key[index].first_page == first_page);
+			p = relptr_access(base, p->internal_key[index - 1].child);
 			break;
 		}
 		Assert(index == 0);
@@ -803,7 +803,7 @@ FreePageBtreeFindLeftSibling(char *base, FreePageBtree *btp)
 	while (levels > 0)
 	{
 		Assert(p->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
-		p = relptr_access(base, p->u.internal_key[p->hdr.nused - 1].child);
+		p = relptr_access(base, p->internal_key[p->hdr.nused - 1].child);
 		--levels;
 	}
 	Assert(p->hdr.magic == btp->hdr.magic);
@@ -836,8 +836,8 @@ FreePageBtreeFindRightSibling(char *base, FreePageBtree *btp)
 		index = FreePageBtreeSearchInternal(p, first_page);
 		if (index < p->hdr.nused - 1)
 		{
-			Assert(p->u.internal_key[index].first_page == first_page);
-			p = relptr_access(base, p->u.internal_key[index + 1].child);
+			Assert(p->internal_key[index].first_page == first_page);
+			p = relptr_access(base, p->internal_key[index + 1].child);
 			break;
 		}
 		Assert(index == p->hdr.nused - 1);
@@ -848,7 +848,7 @@ FreePageBtreeFindRightSibling(char *base, FreePageBtree *btp)
 	while (levels > 0)
 	{
 		Assert(p->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
-		p = relptr_access(base, p->u.internal_key[0].child);
+		p = relptr_access(base, p->internal_key[0].child);
 		--levels;
 	}
 	Assert(p->hdr.magic == btp->hdr.magic);
@@ -865,11 +865,11 @@ FreePageBtreeFirstKey(FreePageBtree *btp)
 	Assert(btp->hdr.nused > 0);
 
 	if (btp->hdr.magic == FREE_PAGE_LEAF_MAGIC)
-		return btp->u.leaf_key[0].first_page;
+		return btp->leaf_key[0].first_page;
 	else
 	{
 		Assert(btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
-		return btp->u.internal_key[0].first_page;
+		return btp->internal_key[0].first_page;
 	}
 }
 
@@ -903,10 +903,10 @@ FreePageBtreeInsertInternal(char *base, FreePageBtree *btp, Size index,
 	Assert(btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
 	Assert(btp->hdr.nused <= FPM_ITEMS_PER_INTERNAL_PAGE);
 	Assert(index <= btp->hdr.nused);
-	memmove(&btp->u.internal_key[index + 1], &btp->u.internal_key[index],
+	memmove(&btp->internal_key[index + 1], &btp->internal_key[index],
 			sizeof(FreePageBtreeInternalKey) * (btp->hdr.nused - index));
-	btp->u.internal_key[index].first_page = first_page;
-	relptr_store(base, btp->u.internal_key[index].child, child);
+	btp->internal_key[index].first_page = first_page;
+	relptr_store(base, btp->internal_key[index].child, child);
 	++btp->hdr.nused;
 }
 
@@ -920,10 +920,10 @@ FreePageBtreeInsertLeaf(FreePageBtree *btp, Size index, Size first_page,
 	Assert(btp->hdr.magic == FREE_PAGE_LEAF_MAGIC);
 	Assert(btp->hdr.nused <= FPM_ITEMS_PER_LEAF_PAGE);
 	Assert(index <= btp->hdr.nused);
-	memmove(&btp->u.leaf_key[index + 1], &btp->u.leaf_key[index],
+	memmove(&btp->leaf_key[index + 1], &btp->leaf_key[index],
 			sizeof(FreePageBtreeLeafKey) * (btp->hdr.nused - index));
-	btp->u.leaf_key[index].first_page = first_page;
-	btp->u.leaf_key[index].npages = npages;
+	btp->leaf_key[index].first_page = first_page;
+	btp->leaf_key[index].npages = npages;
 	++btp->hdr.nused;
 }
 
@@ -967,7 +967,7 @@ FreePageBtreeRemove(FreePageManager *fpm, FreePageBtree *btp, Size index)
 	/* Physically remove the key from the page. */
 	--btp->hdr.nused;
 	if (index < btp->hdr.nused)
-		memmove(&btp->u.leaf_key[index], &btp->u.leaf_key[index + 1],
+		memmove(&btp->leaf_key[index], &btp->leaf_key[index + 1],
 				sizeof(FreePageBtreeLeafKey) * (btp->hdr.nused - index));
 
 	/* If we just removed the first key, adjust ancestor keys. */
@@ -1021,8 +1021,8 @@ FreePageBtreeRemovePage(FreePageManager *fpm, FreePageBtree *btp)
 		index = FreePageBtreeSearchLeaf(parent, first_page);
 		Assert(index < parent->hdr.nused);
 		if (index < parent->hdr.nused - 1)
-			memmove(&parent->u.leaf_key[index],
-					&parent->u.leaf_key[index + 1],
+			memmove(&parent->leaf_key[index],
+					&parent->leaf_key[index + 1],
 					sizeof(FreePageBtreeLeafKey)
 					* (parent->hdr.nused - index - 1));
 	}
@@ -1031,8 +1031,8 @@ FreePageBtreeRemovePage(FreePageManager *fpm, FreePageBtree *btp)
 		index = FreePageBtreeSearchInternal(parent, first_page);
 		Assert(index < parent->hdr.nused);
 		if (index < parent->hdr.nused - 1)
-			memmove(&parent->u.internal_key[index],
-					&parent->u.internal_key[index + 1],
+			memmove(&parent->internal_key[index],
+					&parent->internal_key[index + 1],
 					sizeof(FreePageBtreeInternalKey)
 					* (parent->hdr.nused - index - 1));
 	}
@@ -1086,7 +1086,7 @@ FreePageBtreeSearch(FreePageManager *fpm, Size first_page,
 
 		index = FreePageBtreeSearchInternal(btp, first_page);
 		found_exact = index < btp->hdr.nused &&
-			btp->u.internal_key[index].first_page == first_page;
+			btp->internal_key[index].first_page == first_page;
 
 		/*
 		 * If we found an exact match we descend directly.  Otherwise, we
@@ -1107,7 +1107,7 @@ FreePageBtreeSearch(FreePageManager *fpm, Size first_page,
 
 		/* Descend to appropriate child page. */
 		Assert(index < btp->hdr.nused);
-		child = relptr_access(base, btp->u.internal_key[index].child);
+		child = relptr_access(base, btp->internal_key[index].child);
 		Assert(relptr_access(base, child->hdr.parent) == btp);
 		btp = child;
 	}
@@ -1128,7 +1128,7 @@ FreePageBtreeSearch(FreePageManager *fpm, Size first_page,
 	result->page = btp;
 	result->index = index;
 	result->found = index < btp->hdr.nused &&
-		first_page == btp->u.leaf_key[index].first_page;
+		first_page == btp->leaf_key[index].first_page;
 }
 
 /*
@@ -1148,7 +1148,7 @@ FreePageBtreeSearchInternal(FreePageBtree *btp, Size first_page)
 	while (low < high)
 	{
 		Size		mid = (low + high) / 2;
-		Size		val = btp->u.internal_key[mid].first_page;
+		Size		val = btp->internal_key[mid].first_page;
 
 		if (first_page == val)
 			return mid;
@@ -1178,7 +1178,7 @@ FreePageBtreeSearchLeaf(FreePageBtree *btp, Size first_page)
 	while (low < high)
 	{
 		Size		mid = (low + high) / 2;
-		Size		val = btp->u.leaf_key[mid].first_page;
+		Size		val = btp->leaf_key[mid].first_page;
 
 		if (first_page == val)
 			return mid;
@@ -1209,14 +1209,14 @@ FreePageBtreeSplitPage(FreePageManager *fpm, FreePageBtree *btp)
 	btp->hdr.nused -= newsibling->hdr.nused;
 
 	if (btp->hdr.magic == FREE_PAGE_LEAF_MAGIC)
-		memcpy(&newsibling->u.leaf_key,
-			   &btp->u.leaf_key[btp->hdr.nused],
+		memcpy(&newsibling->leaf_key,
+			   &btp->leaf_key[btp->hdr.nused],
 			   sizeof(FreePageBtreeLeafKey) * newsibling->hdr.nused);
 	else
 	{
 		Assert(btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC);
-		memcpy(&newsibling->u.internal_key,
-			   &btp->u.internal_key[btp->hdr.nused],
+		memcpy(&newsibling->internal_key,
+			   &btp->internal_key[btp->hdr.nused],
 			   sizeof(FreePageBtreeInternalKey) * newsibling->hdr.nused);
 		FreePageBtreeUpdateParentPointers(fpm_segment_base(fpm), newsibling);
 	}
@@ -1238,7 +1238,7 @@ FreePageBtreeUpdateParentPointers(char *base, FreePageBtree *btp)
 	{
 		FreePageBtree *child;
 
-		child = relptr_access(base, btp->u.internal_key[i].child);
+		child = relptr_access(base, btp->internal_key[i].child);
 		relptr_store(base, child->hdr.parent, btp);
 	}
 }
@@ -1268,12 +1268,12 @@ FreePageManagerDumpBtree(FreePageManager *fpm, FreePageBtree *btp,
 	{
 		if (btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC)
 			appendStringInfo(buf, " %zu->%zu",
-							 btp->u.internal_key[index].first_page,
-							 relptr_offset(btp->u.internal_key[index].child) / FPM_PAGE_SIZE);
+							 btp->internal_key[index].first_page,
+							 relptr_offset(btp->internal_key[index].child) / FPM_PAGE_SIZE);
 		else
 			appendStringInfo(buf, " %zu(%zu)",
-							 btp->u.leaf_key[index].first_page,
-							 btp->u.leaf_key[index].npages);
+							 btp->leaf_key[index].first_page,
+							 btp->leaf_key[index].npages);
 	}
 	appendStringInfoChar(buf, '\n');
 
@@ -1283,7 +1283,7 @@ FreePageManagerDumpBtree(FreePageManager *fpm, FreePageBtree *btp,
 		{
 			FreePageBtree *child;
 
-			child = relptr_access(base, btp->u.internal_key[index].child);
+			child = relptr_access(base, btp->internal_key[index].child);
 			FreePageManagerDumpBtree(fpm, child, btp, level + 1, buf);
 		}
 	}
@@ -1445,7 +1445,7 @@ FreePageManagerGetInternal(FreePageManager *fpm, Size npages, Size *first_page)
 
 			/* Adjust btree to reflect remaining pages. */
 			Assert(victim->npages > npages);
-			key = &result.page->u.leaf_key[result.index];
+			key = &result.page->leaf_key[result.index];
 			Assert(key->npages == victim->npages);
 			key->first_page += npages;
 			key->npages -= npages;
@@ -1538,8 +1538,8 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 			root->hdr.magic = FREE_PAGE_LEAF_MAGIC;
 			root->hdr.nused = 1;
 			relptr_store(base, root->hdr.parent, (FreePageBtree *) NULL);
-			root->u.leaf_key[0].first_page = fpm->singleton_first_page;
-			root->u.leaf_key[0].npages = fpm->singleton_npages;
+			root->leaf_key[0].first_page = fpm->singleton_first_page;
+			root->leaf_key[0].npages = fpm->singleton_npages;
 			relptr_store(base, fpm->btree_root, root);
 			fpm->singleton_first_page = 0;
 			fpm->singleton_npages = 0;
@@ -1551,10 +1551,10 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 			 * page run, which is invalid.  Overwrite it with the entry we're
 			 * trying to insert and get out.
 			 */
-			if (root->u.leaf_key[0].npages == 0)
+			if (root->leaf_key[0].npages == 0)
 			{
-				root->u.leaf_key[0].first_page = first_page;
-				root->u.leaf_key[0].npages = npages;
+				root->leaf_key[0].first_page = first_page;
+				root->leaf_key[0].npages = npages;
 				FreePagePushSpanLeader(fpm, first_page, npages);
 				return npages;
 			}
@@ -1567,19 +1567,19 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 	FreePageBtreeSearch(fpm, first_page, &result);
 	Assert(!result.found);
 	if (result.index > 0)
-		prevkey = &result.page->u.leaf_key[result.index - 1];
+		prevkey = &result.page->leaf_key[result.index - 1];
 	if (result.index < result.page->hdr.nused)
 	{
 		np = result.page;
 		nindex = result.index;
-		nextkey = &result.page->u.leaf_key[result.index];
+		nextkey = &result.page->leaf_key[result.index];
 	}
 	else
 	{
 		np = FreePageBtreeFindRightSibling(base, result.page);
 		nindex = 0;
 		if (np != NULL)
-			nextkey = &np->u.leaf_key[0];
+			nextkey = &np->leaf_key[0];
 	}
 
 	/* Consolidate with the previous entry if possible. */
@@ -1742,7 +1742,7 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 					Size		index;
 					FreePageBtree *insert_into;
 
-					insert_into = key < newsibling->u.leaf_key[0].first_page ?
+					insert_into = key < newsibling->leaf_key[0].first_page ?
 						split_target : newsibling;
 					index = FreePageBtreeSearchLeaf(insert_into, key);
 					FreePageBtreeInsertLeaf(insert_into, index, key, npages);
@@ -1755,7 +1755,7 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 					FreePageBtree *insert_into;
 
 					insert_into =
-						key < newsibling->u.internal_key[0].first_page ?
+						key < newsibling->internal_key[0].first_page ?
 						split_target : newsibling;
 					index = FreePageBtreeSearchInternal(insert_into, key);
 					FreePageBtreeInsertInternal(base, insert_into, index,
@@ -1775,14 +1775,14 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 					newroot->hdr.nused = 2;
 					relptr_store(base, newroot->hdr.parent,
 								 (FreePageBtree *) NULL);
-					newroot->u.internal_key[0].first_page =
+					newroot->internal_key[0].first_page =
 						FreePageBtreeFirstKey(split_target);
-					relptr_store(base, newroot->u.internal_key[0].child,
+					relptr_store(base, newroot->internal_key[0].child,
 								 split_target);
 					relptr_store(base, split_target->hdr.parent, newroot);
-					newroot->u.internal_key[1].first_page =
+					newroot->internal_key[1].first_page =
 						FreePageBtreeFirstKey(newsibling);
-					relptr_store(base, newroot->u.internal_key[1].child,
+					relptr_store(base, newroot->internal_key[1].child,
 								 newsibling);
 					relptr_store(base, newsibling->hdr.parent, newroot);
 					relptr_store(base, fpm->btree_root, newroot);
@@ -1792,7 +1792,7 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages,
 				}
 
 				/* If the parent page isn't full, insert the downlink. */
-				key = newsibling->u.internal_key[0].first_page;
+				key = newsibling->internal_key[0].first_page;
 				if (parent->hdr.nused < FPM_ITEMS_PER_INTERNAL_PAGE)
 				{
 					Size		index;
-- 
2.51.0

From c73ec4d876b12cc8a0ee17db7555d2f67df434ab Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 17/23] C11 anonymous unions [typcache]

---
 src/backend/utils/cache/typcache.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 6a347698edf..360fd029ef9 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -200,7 +200,7 @@ typedef struct SharedRecordTableKey
 	{
 		TupleDesc	local_tupdesc;
 		dsa_pointer shared_tupdesc;
-	}			u;
+	};
 	bool		shared;
 } SharedRecordTableKey;
 
@@ -241,14 +241,14 @@ shared_record_table_compare(const void *a, const void *b, size_t size,
 	TupleDesc	t2;
 
 	if (k1->shared)
-		t1 = (TupleDesc) dsa_get_address(area, k1->u.shared_tupdesc);
+		t1 = (TupleDesc) dsa_get_address(area, k1->shared_tupdesc);
 	else
-		t1 = k1->u.local_tupdesc;
+		t1 = k1->local_tupdesc;
 
 	if (k2->shared)
-		t2 = (TupleDesc) dsa_get_address(area, k2->u.shared_tupdesc);
+		t2 = (TupleDesc) dsa_get_address(area, k2->shared_tupdesc);
 	else
-		t2 = k2->u.local_tupdesc;
+		t2 = k2->local_tupdesc;
 
 	return equalRowTypes(t1, t2) ? 0 : 1;
 }
@@ -264,9 +264,9 @@ shared_record_table_hash(const void *a, size_t size, void *arg)
 	TupleDesc	t;
 
 	if (k->shared)
-		t = (TupleDesc) dsa_get_address(area, k->u.shared_tupdesc);
+		t = (TupleDesc) dsa_get_address(area, k->shared_tupdesc);
 	else
-		t = k->u.local_tupdesc;
+		t = k->local_tupdesc;
 
 	return hashRowType(t);
 }
@@ -2256,14 +2256,14 @@ SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *registry,
 
 		/* Insert into the record table. */
 		record_table_key.shared = false;
-		record_table_key.u.local_tupdesc = tupdesc;
+		record_table_key.local_tupdesc = tupdesc;
 		record_table_entry = dshash_find_or_insert(record_table,
 												   &record_table_key,
 												   &found);
 		if (!found)
 		{
 			record_table_entry->key.shared = true;
-			record_table_entry->key.u.shared_tupdesc = shared_dp;
+			record_table_entry->key.shared_tupdesc = shared_dp;
 		}
 		dshash_release_lock(record_table, record_table_entry);
 	}
@@ -2955,7 +2955,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc)
 
 	/* Try to find a matching tuple descriptor in the record table. */
 	key.shared = false;
-	key.u.local_tupdesc = tupdesc;
+	key.local_tupdesc = tupdesc;
 	record_table_entry = (SharedRecordTableEntry *)
 		dshash_find(CurrentSession->shared_record_table, &key, false);
 	if (record_table_entry)
@@ -2965,7 +2965,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc)
 							record_table_entry);
 		result = (TupleDesc)
 			dsa_get_address(CurrentSession->area,
-							record_table_entry->key.u.shared_tupdesc);
+							record_table_entry->key.shared_tupdesc);
 		Assert(result->tdrefcount == -1);
 
 		return result;
@@ -3028,7 +3028,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc)
 		Assert(record_table_entry->key.shared);
 		result = (TupleDesc)
 			dsa_get_address(CurrentSession->area,
-							record_table_entry->key.u.shared_tupdesc);
+							record_table_entry->key.shared_tupdesc);
 		Assert(result->tdrefcount == -1);
 
 		return result;
@@ -3036,7 +3036,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc)
 
 	/* Store it and return it. */
 	record_table_entry->key.shared = true;
-	record_table_entry->key.u.shared_tupdesc = shared_dp;
+	record_table_entry->key.shared_tupdesc = shared_dp;
 	dshash_release_lock(CurrentSession->shared_record_table,
 						record_table_entry);
 	result = (TupleDesc)
-- 
2.51.0

From 07b929eb8fe3d9cff56c47da55193258d4e3b3e6 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:48 +0200
Subject: [PATCH 18/23] C11 anonymous unions [tsrank]

---
 src/backend/utils/adt/tsrank.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c
index e863aa58653..1354520a5e9 100644
--- a/src/backend/utils/adt/tsrank.c
+++ b/src/backend/utils/adt/tsrank.c
@@ -516,7 +516,7 @@ typedef struct
 			QueryItem  *item;
 			WordEntry  *entry;
 		}			map;
-	}			data;
+	};
 	WordEntryPos pos;
 } DocRepresentation;
 
@@ -530,10 +530,10 @@ compareDocR(const void *va, const void *vb)
 	{
 		if (WEP_GETWEIGHT(a->pos) == WEP_GETWEIGHT(b->pos))
 		{
-			if (a->data.map.entry == b->data.map.entry)
+			if (a->map.entry == b->map.entry)
 				return 0;
 
-			return (a->data.map.entry > b->data.map.entry) ? 1 : -1;
+			return (a->map.entry > b->map.entry) ? 1 : -1;
 		}
 
 		return (WEP_GETWEIGHT(a->pos) > WEP_GETWEIGHT(b->pos)) ? 1 : -1;
@@ -614,12 +614,12 @@ fillQueryRepresentationData(QueryRepresentation *qr, DocRepresentation *entry)
 	int			lastPos;
 	QueryRepresentationOperand *opData;
 
-	for (i = 0; i < entry->data.query.nitem; i++)
+	for (i = 0; i < entry->query.nitem; i++)
 	{
-		if (entry->data.query.items[i]->type != QI_VAL)
+		if (entry->query.items[i]->type != QI_VAL)
 			continue;
 
-		opData = QR_GET_OPERAND_DATA(qr, entry->data.query.items[i]);
+		opData = QR_GET_OPERAND_DATA(qr, entry->query.items[i]);
 
 		opData->operandexists = true;
 
@@ -790,8 +790,8 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
 					curoperand->weight & (1 << WEP_GETWEIGHT(post[j])))
 				{
 					doc[cur].pos = post[j];
-					doc[cur].data.map.entry = entry;
-					doc[cur].data.map.item = (QueryItem *) curoperand;
+					doc[cur].map.entry = entry;
+					doc[cur].map.item = (QueryItem *) curoperand;
 					cur++;
 				}
 			}
@@ -815,26 +815,26 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
 		 * Join QueryItem per WordEntry and its position
 		 */
 		storage.pos = doc->pos;
-		storage.data.query.items = palloc(sizeof(QueryItem *) * qr->query->size);
-		storage.data.query.items[0] = doc->data.map.item;
-		storage.data.query.nitem = 1;
+		storage.query.items = palloc(sizeof(QueryItem *) * qr->query->size);
+		storage.query.items[0] = doc->map.item;
+		storage.query.nitem = 1;
 
 		while (rptr - doc < cur)
 		{
 			if (rptr->pos == (rptr - 1)->pos &&
-				rptr->data.map.entry == (rptr - 1)->data.map.entry)
+				rptr->map.entry == (rptr - 1)->map.entry)
 			{
-				storage.data.query.items[storage.data.query.nitem] = rptr->data.map.item;
-				storage.data.query.nitem++;
+				storage.query.items[storage.query.nitem] = rptr->map.item;
+				storage.query.nitem++;
 			}
 			else
 			{
 				*wptr = storage;
 				wptr++;
 				storage.pos = rptr->pos;
-				storage.data.query.items = palloc(sizeof(QueryItem *) * qr->query->size);
-				storage.data.query.items[0] = rptr->data.map.item;
-				storage.data.query.nitem = 1;
+				storage.query.items = palloc(sizeof(QueryItem *) * qr->query->size);
+				storage.query.items[0] = rptr->map.item;
+				storage.query.nitem = 1;
 			}
 
 			rptr++;
-- 
2.51.0

From e3d52a3812e660608118c2d58236dd8164fc9a6b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:49 +0200
Subject: [PATCH 19/23] C11 anonymous unions [fd]

---
 src/backend/storage/file/fd.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index a4ec7959f31..c222a442a8d 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -261,7 +261,7 @@ typedef struct
 		FILE	   *file;
 		DIR		   *dir;
 		int			fd;
-	}			desc;
+	};
 } AllocateDesc;
 
 static int	numAllocatedDescs = 0;
@@ -2661,10 +2661,10 @@ AllocateFile(const char *name, const char *mode)
 		AllocateDesc *desc = &allocatedDescs[numAllocatedDescs];
 
 		desc->kind = AllocateDescFile;
-		desc->desc.file = file;
+		desc->file = file;
 		desc->create_subid = GetCurrentSubTransactionId();
 		numAllocatedDescs++;
-		return desc->desc.file;
+		return desc->file;
 	}
 
 	if (errno == EMFILE || errno == ENFILE)
@@ -2721,7 +2721,7 @@ OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
 		AllocateDesc *desc = &allocatedDescs[numAllocatedDescs];
 
 		desc->kind = AllocateDescRawFD;
-		desc->desc.fd = fd;
+		desc->fd = fd;
 		desc->create_subid = GetCurrentSubTransactionId();
 		numAllocatedDescs++;
 
@@ -2772,10 +2772,10 @@ OpenPipeStream(const char *command, const char *mode)
 		AllocateDesc *desc = &allocatedDescs[numAllocatedDescs];
 
 		desc->kind = AllocateDescPipe;
-		desc->desc.file = file;
+		desc->file = file;
 		desc->create_subid = GetCurrentSubTransactionId();
 		numAllocatedDescs++;
-		return desc->desc.file;
+		return desc->file;
 	}
 
 	if (errno == EMFILE || errno == ENFILE)
@@ -2805,17 +2805,17 @@ FreeDesc(AllocateDesc *desc)
 	switch (desc->kind)
 	{
 		case AllocateDescFile:
-			result = fclose(desc->desc.file);
+			result = fclose(desc->file);
 			break;
 		case AllocateDescPipe:
-			result = pclose(desc->desc.file);
+			result = pclose(desc->file);
 			break;
 		case AllocateDescDir:
-			result = closedir(desc->desc.dir);
+			result = closedir(desc->dir);
 			break;
 		case AllocateDescRawFD:
-			pgaio_closing_fd(desc->desc.fd);
-			result = close(desc->desc.fd);
+			pgaio_closing_fd(desc->fd);
+			result = close(desc->fd);
 			break;
 		default:
 			elog(ERROR, "AllocateDesc kind not recognized");
@@ -2848,7 +2848,7 @@ FreeFile(FILE *file)
 	{
 		AllocateDesc *desc = &allocatedDescs[i];
 
-		if (desc->kind == AllocateDescFile && desc->desc.file == file)
+		if (desc->kind == AllocateDescFile && desc->file == file)
 			return FreeDesc(desc);
 	}
 
@@ -2876,7 +2876,7 @@ CloseTransientFile(int fd)
 	{
 		AllocateDesc *desc = &allocatedDescs[i];
 
-		if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
+		if (desc->kind == AllocateDescRawFD && desc->fd == fd)
 			return FreeDesc(desc);
 	}
 
@@ -2924,10 +2924,10 @@ AllocateDir(const char *dirname)
 		AllocateDesc *desc = &allocatedDescs[numAllocatedDescs];
 
 		desc->kind = AllocateDescDir;
-		desc->desc.dir = dir;
+		desc->dir = dir;
 		desc->create_subid = GetCurrentSubTransactionId();
 		numAllocatedDescs++;
-		return desc->desc.dir;
+		return desc->dir;
 	}
 
 	if (errno == EMFILE || errno == ENFILE)
@@ -3034,7 +3034,7 @@ FreeDir(DIR *dir)
 	{
 		AllocateDesc *desc = &allocatedDescs[i];
 
-		if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
+		if (desc->kind == AllocateDescDir && desc->dir == dir)
 			return FreeDesc(desc);
 	}
 
@@ -3060,7 +3060,7 @@ ClosePipeStream(FILE *file)
 	{
 		AllocateDesc *desc = &allocatedDescs[i];
 
-		if (desc->kind == AllocateDescPipe && desc->desc.file == file)
+		if (desc->kind == AllocateDescPipe && desc->file == file)
 			return FreeDesc(desc);
 	}
 
-- 
2.51.0

From 834a171516ef957f77edb4180b5cd7af5eada698 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:49 +0200
Subject: [PATCH 20/23] C11 anonymous unions [HeapTupleFields]

---
 src/backend/access/heap/heapam_xlog.c |  2 +-
 src/include/access/htup_details.h     | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/backend/access/heap/heapam_xlog.c b/src/backend/access/heap/heapam_xlog.c
index cf843277938..f51af454284 100644
--- a/src/backend/access/heap/heapam_xlog.c
+++ b/src/backend/access/heap/heapam_xlog.c
@@ -1301,7 +1301,7 @@ heap_mask(char *pagedata, BlockNumber blkno)
 			 * During replay, we set Command Id to FirstCommandId. Hence, mask
 			 * it. See heap_xlog_insert() for details.
 			 */
-			page_htup->t_choice.t_heap.t_field3.t_cid = MASK_MARKER;
+			page_htup->t_choice.t_heap.t_cid = MASK_MARKER;
 
 			/*
 			 * For a speculative tuple, heap_insert() does not set ctid in the
diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
index fa4525e3f58..4aea2d658c6 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -128,7 +128,7 @@ typedef struct HeapTupleFields
 	{
 		CommandId	t_cid;		/* inserting or deleting command ID, or both */
 		TransactionId t_xvac;	/* old-style VACUUM FULL xact ID */
-	}			t_field3;
+	};
 } HeapTupleFields;
 
 typedef struct DatumTupleFields
@@ -419,7 +419,7 @@ HeapTupleHeaderGetUpdateXid(const HeapTupleHeaderData *tup)
 static inline CommandId
 HeapTupleHeaderGetRawCommandId(const HeapTupleHeaderData *tup)
 {
-	return tup->t_choice.t_heap.t_field3.t_cid;
+	return tup->t_choice.t_heap.t_cid;
 }
 
 /* SetCmin is reasonably simple since we never need a combo CID */
@@ -427,7 +427,7 @@ static inline void
 HeapTupleHeaderSetCmin(HeapTupleHeaderData *tup, CommandId cid)
 {
 	Assert(!(tup->t_infomask & HEAP_MOVED));
-	tup->t_choice.t_heap.t_field3.t_cid = cid;
+	tup->t_choice.t_heap.t_cid = cid;
 	tup->t_infomask &= ~HEAP_COMBOCID;
 }
 
@@ -436,7 +436,7 @@ static inline void
 HeapTupleHeaderSetCmax(HeapTupleHeaderData *tup, CommandId cid, bool iscombo)
 {
 	Assert(!((tup)->t_infomask & HEAP_MOVED));
-	tup->t_choice.t_heap.t_field3.t_cid = cid;
+	tup->t_choice.t_heap.t_cid = cid;
 	if (iscombo)
 		tup->t_infomask |= HEAP_COMBOCID;
 	else
@@ -447,7 +447,7 @@ static inline TransactionId
 HeapTupleHeaderGetXvac(const HeapTupleHeaderData *tup)
 {
 	if (tup->t_infomask & HEAP_MOVED)
-		return tup->t_choice.t_heap.t_field3.t_xvac;
+		return tup->t_choice.t_heap.t_xvac;
 	else
 		return InvalidTransactionId;
 }
@@ -456,7 +456,7 @@ static inline void
 HeapTupleHeaderSetXvac(HeapTupleHeaderData *tup, TransactionId xid)
 {
 	Assert(tup->t_infomask & HEAP_MOVED);
-	tup->t_choice.t_heap.t_field3.t_xvac = xid;
+	tup->t_choice.t_heap.t_xvac = xid;
 }
 
 StaticAssertDecl(MaxOffsetNumber < SpecTokenOffsetNumber,
-- 
2.51.0

From ea0b3b5a6242b3e56341680a2a333f944e6c1967 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:49 +0200
Subject: [PATCH 21/23] C11 anonymous unions [testint128]

---
 src/test/modules/test_int128/test_int128.c | 108 ++++++++++-----------
 1 file changed, 54 insertions(+), 54 deletions(-)

diff --git a/src/test/modules/test_int128/test_int128.c b/src/test/modules/test_int128/test_int128.c
index c9c17a73a4e..b6053efaf24 100644
--- a/src/test/modules/test_int128/test_int128.c
+++ b/src/test/modules/test_int128/test_int128.c
@@ -50,7 +50,7 @@ typedef union
 		uint64		lo;
 		int64		hi;
 #endif
-	}			hl;
+	};
 }			test128;
 
 #define INT128_HEX_FORMAT	"%016" PRIx64 "%016" PRIx64
@@ -102,140 +102,140 @@ main(int argc, char **argv)
 		int32		r2;
 
 		/* check unsigned addition */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
 		t1.i128 += (int128) (uint64) z;
 		int128_add_uint64(&t2.I128, (uint64) z);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " + unsigned %016" PRIx64 "\n", x, y, z);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check signed addition */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
 		t1.i128 += (int128) z;
 		int128_add_int64(&t2.I128, z);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " + signed %016" PRIx64 "\n", x, y, z);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check 128-bit signed addition */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
-		t3.hl.hi = z;
-		t3.hl.lo = w;
+		t3.hi = z;
+		t3.lo = w;
 		t1.i128 += t3.i128;
 		int128_add_int128(&t2.I128, t3.I128);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " + " INT128_HEX_FORMAT "\n", x, y, z, w);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check unsigned subtraction */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
 		t1.i128 -= (int128) (uint64) z;
 		int128_sub_uint64(&t2.I128, (uint64) z);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " - unsigned %016" PRIx64 "\n", x, y, z);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check signed subtraction */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
 		t1.i128 -= (int128) z;
 		int128_sub_int64(&t2.I128, z);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " - signed %016" PRIx64 "\n", x, y, z);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check 64x64-bit multiply-add */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
 		t1.i128 += (int128) z * (int128) w;
 		int128_add_int64_mul_int64(&t2.I128, z, w);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " + %016" PRIx64 " * %016" PRIx64 "\n", x, y, z, w);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check 64x64-bit multiply-subtract */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
+		t1.hi = x;
+		t1.lo = y;
 		t2 = t1;
 		t1.i128 -= (int128) z * (int128) w;
 		int128_sub_int64_mul_int64(&t2.I128, z, w);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
 			printf(INT128_HEX_FORMAT " - %016" PRIx64 " * %016" PRIx64 "\n", x, y, z, w);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check 128/32-bit division */
-		t3.hl.hi = x;
-		t3.hl.lo = y;
+		t3.hi = x;
+		t3.lo = y;
 		t1.i128 = t3.i128 / z32;
 		r1 = (int32) (t3.i128 % z32);
 		t2 = t3;
 		int128_div_mod_int32(&t2.I128, z32, &r2);
 
-		if (t1.hl.hi != t2.hl.hi || t1.hl.lo != t2.hl.lo)
+		if (t1.hi != t2.hi || t1.lo != t2.lo)
 		{
-			printf(INT128_HEX_FORMAT " / signed %08X\n", t3.hl.hi, t3.hl.lo, z32);
-			printf("native = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("result = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf(INT128_HEX_FORMAT " / signed %08X\n", t3.hi, t3.lo, z32);
+			printf("native = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("result = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 		if (r1 != r2)
 		{
-			printf(INT128_HEX_FORMAT " %% signed %08X\n", t3.hl.hi, t3.hl.lo, z32);
+			printf(INT128_HEX_FORMAT " %% signed %08X\n", t3.hi, t3.lo, z32);
 			printf("native = %08X\n", r1);
 			printf("result = %08X\n", r2);
 			return 1;
 		}
 
 		/* check comparison */
-		t1.hl.hi = x;
-		t1.hl.lo = y;
-		t2.hl.hi = z;
-		t2.hl.lo = w;
+		t1.hi = x;
+		t1.lo = y;
+		t2.hi = z;
+		t2.lo = w;
 
 		if (my_int128_compare(t1.i128, t2.i128) !=
 			int128_compare(t1.I128, t2.I128))
@@ -243,13 +243,13 @@ main(int argc, char **argv)
 			printf("comparison failure: %d vs %d\n",
 				   my_int128_compare(t1.i128, t2.i128),
 				   int128_compare(t1.I128, t2.I128));
-			printf("arg1 = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("arg2 = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("arg1 = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("arg2 = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 
 		/* check case with identical hi parts; above will hardly ever hit it */
-		t2.hl.hi = x;
+		t2.hi = x;
 
 		if (my_int128_compare(t1.i128, t2.i128) !=
 			int128_compare(t1.I128, t2.I128))
@@ -257,8 +257,8 @@ main(int argc, char **argv)
 			printf("comparison failure: %d vs %d\n",
 				   my_int128_compare(t1.i128, t2.i128),
 				   int128_compare(t1.I128, t2.I128));
-			printf("arg1 = " INT128_HEX_FORMAT "\n", t1.hl.hi, t1.hl.lo);
-			printf("arg2 = " INT128_HEX_FORMAT "\n", t2.hl.hi, t2.hl.lo);
+			printf("arg1 = " INT128_HEX_FORMAT "\n", t1.hi, t1.lo);
+			printf("arg2 = " INT128_HEX_FORMAT "\n", t2.hi, t2.lo);
 			return 1;
 		}
 	}
-- 
2.51.0

From c04f20851266020f06c313a100de05c6dedbeca3 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:49 +0200
Subject: [PATCH 22/23] C11 anonymous unions [executor]

---
 contrib/hstore/hstore_subs.c          |   4 +-
 src/backend/executor/execExpr.c       | 670 ++++++++++++-------------
 src/backend/executor/execExprInterp.c | 680 +++++++++++++-------------
 src/backend/utils/adt/arraysubs.c     |  14 +-
 src/backend/utils/adt/jsonbsubs.c     |   8 +-
 src/include/executor/execExpr.h       |   2 +-
 src/pl/plpgsql/src/pl_exec.c          |  78 +--
 7 files changed, 728 insertions(+), 728 deletions(-)

diff --git a/contrib/hstore/hstore_subs.c b/contrib/hstore/hstore_subs.c
index 3d03f66fa0d..8342d1ca558 100644
--- a/contrib/hstore/hstore_subs.c
+++ b/contrib/hstore/hstore_subs.c
@@ -95,7 +95,7 @@ hstore_subscript_fetch(ExprState *state,
 					   ExprEvalStep *op,
 					   ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	HStore	   *hs;
 	text	   *key;
 	HEntry	   *entries;
@@ -144,7 +144,7 @@ hstore_subscript_assign(ExprState *state,
 						ExprEvalStep *op,
 						ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	text	   *key;
 	Pairs		p;
 	HStore	   *out;
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index f1569879b52..a3490cb3d9c 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -270,7 +270,7 @@ ExecInitQual(List *qual, PlanState *parent)
 		ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
 
 		/* then emit EEOP_QUAL to detect if it's false (or null) */
-		scratch.d.qualexpr.jumpdone = -1;
+		scratch.qualexpr.jumpdone = -1;
 		ExprEvalPushStep(state, &scratch);
 		adjust_jumps = lappend_int(adjust_jumps,
 								   state->steps_len - 1);
@@ -282,8 +282,8 @@ ExecInitQual(List *qual, PlanState *parent)
 		ExprEvalStep *as = &state->steps[jump];
 
 		Assert(as->opcode == EEOP_QUAL);
-		Assert(as->d.qualexpr.jumpdone == -1);
-		as->d.qualexpr.jumpdone = state->steps_len;
+		Assert(as->qualexpr.jumpdone == -1);
+		as->qualexpr.jumpdone = state->steps_len;
 	}
 
 	/*
@@ -473,8 +473,8 @@ ExecBuildProjectionInfo(List *targetList,
 					break;
 			}
 
-			scratch.d.assign_var.attnum = attnum - 1;
-			scratch.d.assign_var.resultnum = tle->resno - 1;
+			scratch.assign_var.attnum = attnum - 1;
+			scratch.assign_var.resultnum = tle->resno - 1;
 			ExprEvalPushStep(state, &scratch);
 		}
 		else
@@ -498,7 +498,7 @@ ExecBuildProjectionInfo(List *targetList,
 				scratch.opcode = EEOP_ASSIGN_TMP_MAKE_RO;
 			else
 				scratch.opcode = EEOP_ASSIGN_TMP;
-			scratch.d.assign_tmp.resultnum = tle->resno - 1;
+			scratch.assign_tmp.resultnum = tle->resno - 1;
 			ExprEvalPushStep(state, &scratch);
 		}
 	}
@@ -696,15 +696,15 @@ ExecBuildUpdateProjection(List *targetList,
 							&state->resvalue, &state->resnull);
 			/* Needn't worry about read-only-ness here, either. */
 			scratch.opcode = EEOP_ASSIGN_TMP;
-			scratch.d.assign_tmp.resultnum = targetattnum - 1;
+			scratch.assign_tmp.resultnum = targetattnum - 1;
 			ExprEvalPushStep(state, &scratch);
 		}
 		else
 		{
 			/* Just assign from the outer tuple. */
 			scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
-			scratch.d.assign_var.attnum = outerattnum;
-			scratch.d.assign_var.resultnum = targetattnum - 1;
+			scratch.assign_var.attnum = outerattnum;
+			scratch.assign_var.resultnum = targetattnum - 1;
 			ExprEvalPushStep(state, &scratch);
 		}
 		outerattnum++;
@@ -724,20 +724,20 @@ ExecBuildUpdateProjection(List *targetList,
 			scratch.opcode = EEOP_CONST;
 			scratch.resvalue = &state->resvalue;
 			scratch.resnull = &state->resnull;
-			scratch.d.constval.value = (Datum) 0;
-			scratch.d.constval.isnull = true;
+			scratch.constval.value = (Datum) 0;
+			scratch.constval.isnull = true;
 			ExprEvalPushStep(state, &scratch);
 			/* ... then assign it to the result slot */
 			scratch.opcode = EEOP_ASSIGN_TMP;
-			scratch.d.assign_tmp.resultnum = attnum - 1;
+			scratch.assign_tmp.resultnum = attnum - 1;
 			ExprEvalPushStep(state, &scratch);
 		}
 		else if (!bms_is_member(attnum, assignedCols))
 		{
 			/* Certainly the right type, so needn't check */
 			scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
-			scratch.d.assign_var.attnum = attnum - 1;
-			scratch.d.assign_var.resultnum = attnum - 1;
+			scratch.assign_var.attnum = attnum - 1;
+			scratch.assign_var.resultnum = attnum - 1;
 			ExprEvalPushStep(state, &scratch);
 		}
 	}
@@ -944,9 +944,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				else if (variable->varattno <= 0)
 				{
 					/* system column */
-					scratch.d.var.attnum = variable->varattno;
-					scratch.d.var.vartype = variable->vartype;
-					scratch.d.var.varreturningtype = variable->varreturningtype;
+					scratch.var.attnum = variable->varattno;
+					scratch.var.vartype = variable->vartype;
+					scratch.var.varreturningtype = variable->varreturningtype;
 					switch (variable->varno)
 					{
 						case INNER_VAR:
@@ -979,9 +979,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				else
 				{
 					/* regular user column */
-					scratch.d.var.attnum = variable->varattno - 1;
-					scratch.d.var.vartype = variable->vartype;
-					scratch.d.var.varreturningtype = variable->varreturningtype;
+					scratch.var.attnum = variable->varattno - 1;
+					scratch.var.vartype = variable->vartype;
+					scratch.var.varreturningtype = variable->varreturningtype;
 					switch (variable->varno)
 					{
 						case INNER_VAR:
@@ -1021,8 +1021,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				Const	   *con = (Const *) node;
 
 				scratch.opcode = EEOP_CONST;
-				scratch.d.constval.value = con->constvalue;
-				scratch.d.constval.isnull = con->constisnull;
+				scratch.constval.value = con->constvalue;
+				scratch.constval.isnull = con->constisnull;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -1037,8 +1037,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				{
 					case PARAM_EXEC:
 						scratch.opcode = EEOP_PARAM_EXEC;
-						scratch.d.param.paramid = param->paramid;
-						scratch.d.param.paramtype = param->paramtype;
+						scratch.param.paramid = param->paramid;
+						scratch.param.paramtype = param->paramtype;
 						ExprEvalPushStep(state, &scratch);
 						break;
 					case PARAM_EXTERN:
@@ -1064,8 +1064,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 						else
 						{
 							scratch.opcode = EEOP_PARAM_EXTERN;
-							scratch.d.param.paramid = param->paramid;
-							scratch.d.param.paramtype = param->paramtype;
+							scratch.param.paramid = param->paramid;
+							scratch.param.paramtype = param->paramtype;
 							ExprEvalPushStep(state, &scratch);
 						}
 						break;
@@ -1082,7 +1082,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				Aggref	   *aggref = (Aggref *) node;
 
 				scratch.opcode = EEOP_AGGREF;
-				scratch.d.aggref.aggno = aggref->aggno;
+				scratch.aggref.aggno = aggref->aggno;
 
 				if (state->parent && IsA(state->parent, AggState))
 				{
@@ -1114,9 +1114,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				agg = (Agg *) (state->parent->plan);
 
 				if (agg->groupingSets)
-					scratch.d.grouping_func.clauses = grp_node->cols;
+					scratch.grouping_func.clauses = grp_node->cols;
 				else
-					scratch.d.grouping_func.clauses = NIL;
+					scratch.grouping_func.clauses = NIL;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -1163,7 +1163,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				}
 
 				scratch.opcode = EEOP_WINDOW_FUNC;
-				scratch.d.window_func.wfstate = wfstate;
+				scratch.window_func.wfstate = wfstate;
 				ExprEvalPushStep(state, &scratch);
 				break;
 			}
@@ -1246,7 +1246,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				 * that the value passed to the comparison function is a
 				 * read-only pointer.
 				 */
-				scratch.d.func.make_ro =
+				scratch.func.make_ro =
 					(get_typlen(exprType((Node *) linitial(op->args))) == -1);
 
 				/*
@@ -1343,10 +1343,10 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 					/* And perform the operation */
 					scratch.opcode = EEOP_HASHED_SCALARARRAYOP;
-					scratch.d.hashedscalararrayop.inclause = opexpr->useOr;
-					scratch.d.hashedscalararrayop.finfo = finfo;
-					scratch.d.hashedscalararrayop.fcinfo_data = fcinfo;
-					scratch.d.hashedscalararrayop.saop = opexpr;
+					scratch.hashedscalararrayop.inclause = opexpr->useOr;
+					scratch.hashedscalararrayop.finfo = finfo;
+					scratch.hashedscalararrayop.fcinfo_data = fcinfo;
+					scratch.hashedscalararrayop.saop = opexpr;

 					ExprEvalPushStep(state, &scratch);
@@ -1368,11 +1368,11 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 					/* And perform the operation */
 					scratch.opcode = EEOP_SCALARARRAYOP;
-					scratch.d.scalararrayop.element_type = InvalidOid;
-					scratch.d.scalararrayop.useOr = opexpr->useOr;
-					scratch.d.scalararrayop.finfo = finfo;
-					scratch.d.scalararrayop.fcinfo_data = fcinfo;
-					scratch.d.scalararrayop.fn_addr = finfo->fn_addr;
+					scratch.scalararrayop.element_type = InvalidOid;
+					scratch.scalararrayop.useOr = opexpr->useOr;
+					scratch.scalararrayop.finfo = finfo;
+					scratch.scalararrayop.fcinfo_data = fcinfo;
+					scratch.scalararrayop.fn_addr = finfo->fn_addr;
 					ExprEvalPushStep(state, &scratch);
 				}
 				break;
@@ -1388,7 +1388,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				/* allocate scratch memory used by all steps of AND/OR */
 				if (boolexpr->boolop != NOT_EXPR)
-					scratch.d.boolexpr.anynull = (bool *) palloc(sizeof(bool));
+					scratch.boolexpr.anynull = (bool *) palloc(sizeof(bool));
 
 				/*
 				 * For each argument evaluate the argument itself, then
@@ -1445,7 +1445,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 							break;
 					}
 
-					scratch.d.boolexpr.jumpdone = -1;
+					scratch.boolexpr.jumpdone = -1;
 					ExprEvalPushStep(state, &scratch);
 					adjust_jumps = lappend_int(adjust_jumps,
 											   state->steps_len - 1);
@@ -1457,8 +1457,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				{
 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
-					Assert(as->d.boolexpr.jumpdone == -1);
-					as->d.boolexpr.jumpdone = state->steps_len;
+					Assert(as->boolexpr.jumpdone == -1);
+					as->boolexpr.jumpdone = state->steps_len;
 				}
 
 				break;
@@ -1477,8 +1477,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				if (subplan->subLinkType == MULTIEXPR_SUBLINK)
 				{
 					scratch.opcode = EEOP_CONST;
-					scratch.d.constval.value = (Datum) 0;
-					scratch.d.constval.isnull = true;
+					scratch.constval.value = (Datum) 0;
+					scratch.constval.isnull = true;
 					ExprEvalPushStep(state, &scratch);
 					break;
 				}
@@ -1496,9 +1496,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				/* and extract field */
 				scratch.opcode = EEOP_FIELDSELECT;
-				scratch.d.fieldselect.fieldnum = fselect->fieldnum;
-				scratch.d.fieldselect.resulttype = fselect->resulttype;
-				scratch.d.fieldselect.rowcache.cacheptr = NULL;
+				scratch.fieldselect.fieldnum = fselect->fieldnum;
+				scratch.fieldselect.resulttype = fselect->resulttype;
+				scratch.fieldselect.rowcache.cacheptr = NULL;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -1533,11 +1533,11 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				/* next, deform the input tuple into our workspace */
 				scratch.opcode = EEOP_FIELDSTORE_DEFORM;
-				scratch.d.fieldstore.fstore = fstore;
-				scratch.d.fieldstore.rowcache = rowcachep;
-				scratch.d.fieldstore.values = values;
-				scratch.d.fieldstore.nulls = nulls;
-				scratch.d.fieldstore.ncolumns = ncolumns;
+				scratch.fieldstore.fstore = fstore;
+				scratch.fieldstore.rowcache = rowcachep;
+				scratch.fieldstore.values = values;
+				scratch.fieldstore.nulls = nulls;
+				scratch.fieldstore.ncolumns = ncolumns;
 				ExprEvalPushStep(state, &scratch);
 
 				/* evaluate new field values, store in workspace columns */
@@ -1591,11 +1591,11 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				/* finally, form result tuple */
 				scratch.opcode = EEOP_FIELDSTORE_FORM;
-				scratch.d.fieldstore.fstore = fstore;
-				scratch.d.fieldstore.rowcache = rowcachep;
-				scratch.d.fieldstore.values = values;
-				scratch.d.fieldstore.nulls = nulls;
-				scratch.d.fieldstore.ncolumns = ncolumns;
+				scratch.fieldstore.fstore = fstore;
+				scratch.fieldstore.rowcache = rowcachep;
+				scratch.fieldstore.values = values;
+				scratch.fieldstore.nulls = nulls;
+				scratch.fieldstore.ncolumns = ncolumns;
 				ExprEvalPushStep(state, &scratch);
 				break;
 			}
@@ -1634,34 +1634,34 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					scratch.opcode = EEOP_IOCOERCE_SAFE;
 
 				/* lookup the source type's output function */
-				scratch.d.iocoerce.finfo_out = palloc0(sizeof(FmgrInfo));
-				scratch.d.iocoerce.fcinfo_data_out = palloc0(SizeForFunctionCallInfo(1));
+				scratch.iocoerce.finfo_out = palloc0(sizeof(FmgrInfo));
+				scratch.iocoerce.fcinfo_data_out = palloc0(SizeForFunctionCallInfo(1));
 
 				getTypeOutputInfo(exprType((Node *) iocoerce->arg),
 								  &iofunc, &typisvarlena);
-				fmgr_info(iofunc, scratch.d.iocoerce.finfo_out);
-				fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_out);
-				InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_out,
-										 scratch.d.iocoerce.finfo_out,
+				fmgr_info(iofunc, scratch.iocoerce.finfo_out);
+				fmgr_info_set_expr((Node *) node, scratch.iocoerce.finfo_out);
+				InitFunctionCallInfoData(*scratch.iocoerce.fcinfo_data_out,
+										 scratch.iocoerce.finfo_out,
 										 1, InvalidOid, NULL, NULL);
 
 				/* lookup the result type's input function */
-				scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
-				scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3));
+				scratch.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
+				scratch.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3));
 
 				getTypeInputInfo(iocoerce->resulttype,
 								 &iofunc, &typioparam);
-				fmgr_info(iofunc, scratch.d.iocoerce.finfo_in);
-				fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_in);
-				InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_in,
-										 scratch.d.iocoerce.finfo_in,
+				fmgr_info(iofunc, scratch.iocoerce.finfo_in);
+				fmgr_info_set_expr((Node *) node, scratch.iocoerce.finfo_in);
+				InitFunctionCallInfoData(*scratch.iocoerce.fcinfo_data_in,
+										 scratch.iocoerce.finfo_in,
 										 3, InvalidOid, NULL, NULL);
 
 				/*
 				 * We can preload the second and third arguments for the input
 				 * function, since they're constants.
 				 */
-				fcinfo_in = scratch.d.iocoerce.fcinfo_data_in;
+				fcinfo_in = scratch.iocoerce.fcinfo_data_in;
 				fcinfo_in->args[1].value = ObjectIdGetDatum(typioparam);
 				fcinfo_in->args[1].isnull = false;
 				fcinfo_in->args[2].value = Int32GetDatum(-1);
@@ -1721,19 +1721,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				}
 
 				scratch.opcode = EEOP_ARRAYCOERCE;
-				scratch.d.arraycoerce.elemexprstate = elemstate;
-				scratch.d.arraycoerce.resultelemtype = resultelemtype;
+				scratch.arraycoerce.elemexprstate = elemstate;
+				scratch.arraycoerce.resultelemtype = resultelemtype;
 
 				if (elemstate)
 				{
 					/* Set up workspace for array_map */
-					scratch.d.arraycoerce.amstate =
+					scratch.arraycoerce.amstate =
 						(ArrayMapState *) palloc0(sizeof(ArrayMapState));
 				}
 				else
 				{
 					/* Don't need workspace if there's no subexpression */
-					scratch.d.arraycoerce.amstate = NULL;
+					scratch.arraycoerce.amstate = NULL;
 				}
 
 				ExprEvalPushStep(state, &scratch);
@@ -1755,12 +1755,12 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				/* and push conversion step */
 				scratch.opcode = EEOP_CONVERT_ROWTYPE;
-				scratch.d.convert_rowtype.inputtype =
+				scratch.convert_rowtype.inputtype =
 					exprType((Node *) convert->arg);
-				scratch.d.convert_rowtype.outputtype = convert->resulttype;
-				scratch.d.convert_rowtype.incache = &rowcachep[0];
-				scratch.d.convert_rowtype.outcache = &rowcachep[1];
-				scratch.d.convert_rowtype.map = NULL;
+				scratch.convert_rowtype.outputtype = convert->resulttype;
+				scratch.convert_rowtype.incache = &rowcachep[0];
+				scratch.convert_rowtype.outcache = &rowcachep[1];
+				scratch.convert_rowtype.map = NULL;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -1799,8 +1799,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 						scratch.opcode = EEOP_MAKE_READONLY;
 						scratch.resvalue = caseval;
 						scratch.resnull = casenull;
-						scratch.d.make_readonly.value = caseval;
-						scratch.d.make_readonly.isnull = casenull;
+						scratch.make_readonly.value = caseval;
+						scratch.make_readonly.isnull = casenull;
 						ExprEvalPushStep(state, &scratch);
 						/* restore normal settings of scratch fields */
 						scratch.resvalue = resv;
@@ -1844,7 +1844,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 					/* If WHEN result isn't true, jump to next CASE arm */
 					scratch.opcode = EEOP_JUMP_IF_NOT_TRUE;
-					scratch.d.jump.jumpdone = -1;	/* computed later */
+					scratch.jump.jumpdone = -1; /* computed later */
 					ExprEvalPushStep(state, &scratch);
 					whenstep = state->steps_len - 1;
 
@@ -1856,7 +1856,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 					/* Emit JUMP step to jump to end of CASE's code */
 					scratch.opcode = EEOP_JUMP;
-					scratch.d.jump.jumpdone = -1;	/* computed later */
+					scratch.jump.jumpdone = -1; /* computed later */
 					ExprEvalPushStep(state, &scratch);
 
 					/*
@@ -1870,7 +1870,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					 * But we can set WHEN test's jump target now, to make it
 					 * jump to the next WHEN subexpression or the ELSE.
 					 */
-					state->steps[whenstep].d.jump.jumpdone = state->steps_len;
+					state->steps[whenstep].jump.jumpdone = state->steps_len;
 				}
 
 				/* transformCaseExpr always adds a default */
@@ -1886,8 +1886,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
 					Assert(as->opcode == EEOP_JUMP);
-					Assert(as->d.jump.jumpdone == -1);
-					as->d.jump.jumpdone = state->steps_len;
+					Assert(as->jump.jumpdone == -1);
+					as->jump.jumpdone = state->steps_len;
 				}
 
 				break;
@@ -1909,8 +1909,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				else
 				{
 					scratch.opcode = EEOP_CASE_TESTVAL;
-					scratch.d.casetest.value = state->innermost_caseval;
-					scratch.d.casetest.isnull = state->innermost_casenull;
+					scratch.casetest.value = state->innermost_caseval;
+					scratch.casetest.isnull = state->innermost_casenull;
 				}
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -1929,21 +1929,21 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				 * associated with the ARRAYEXPR step.
 				 */
 				scratch.opcode = EEOP_ARRAYEXPR;
-				scratch.d.arrayexpr.elemvalues =
+				scratch.arrayexpr.elemvalues =
 					(Datum *) palloc(sizeof(Datum) * nelems);
-				scratch.d.arrayexpr.elemnulls =
+				scratch.arrayexpr.elemnulls =
 					(bool *) palloc(sizeof(bool) * nelems);
-				scratch.d.arrayexpr.nelems = nelems;
+				scratch.arrayexpr.nelems = nelems;
 
 				/* fill remaining fields of step */
-				scratch.d.arrayexpr.multidims = arrayexpr->multidims;
-				scratch.d.arrayexpr.elemtype = arrayexpr->element_typeid;
+				scratch.arrayexpr.multidims = arrayexpr->multidims;
+				scratch.arrayexpr.elemtype = arrayexpr->element_typeid;
 
 				/* do one-time catalog lookup for type info */
 				get_typlenbyvalalign(arrayexpr->element_typeid,
-									 &scratch.d.arrayexpr.elemlength,
-									 &scratch.d.arrayexpr.elembyval,
-									 &scratch.d.arrayexpr.elemalign);
+									 &scratch.arrayexpr.elemlength,
+									 &scratch.arrayexpr.elembyval,
+									 &scratch.arrayexpr.elemalign);
 
 				/* prepare to evaluate all arguments */
 				elemoff = 0;
@@ -1952,8 +1952,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					Expr	   *e = (Expr *) lfirst(lc);
 
 					ExecInitExprRec(e, state,
-									&scratch.d.arrayexpr.elemvalues[elemoff],
-									&scratch.d.arrayexpr.elemnulls[elemoff]);
+									&scratch.arrayexpr.elemvalues[elemoff],
+									&scratch.arrayexpr.elemnulls[elemoff]);
 					elemoff++;
 				}
 
@@ -2002,15 +2002,15 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				 * a final step forming the composite datum.
 				 */
 				scratch.opcode = EEOP_ROW;
-				scratch.d.row.tupdesc = tupdesc;
+				scratch.row.tupdesc = tupdesc;
 
 				/* space for the individual field datums */
-				scratch.d.row.elemvalues =
+				scratch.row.elemvalues =
 					(Datum *) palloc(sizeof(Datum) * nelems);
-				scratch.d.row.elemnulls =
+				scratch.row.elemnulls =
 					(bool *) palloc(sizeof(bool) * nelems);
 				/* as explained above, make sure any extra columns are null */
-				memset(scratch.d.row.elemnulls, true, sizeof(bool) * nelems);
+				memset(scratch.row.elemnulls, true, sizeof(bool) * nelems);
 
 				/* Set up evaluation, skipping any deleted columns */
 				i = 0;
@@ -2046,8 +2046,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 					/* Evaluate column expr into appropriate workspace slot */
 					ExecInitExprRec(e, state,
-									&scratch.d.row.elemvalues[i],
-									&scratch.d.row.elemnulls[i]);
+									&scratch.row.elemvalues[i],
+									&scratch.row.elemnulls[i]);
 					i++;
 				}
 
@@ -2130,12 +2130,12 @@ ExecInitExprRec(Expr *node, ExprState *state,
 									&fcinfo->args[1].value, &fcinfo->args[1].isnull);
 
 					scratch.opcode = EEOP_ROWCOMPARE_STEP;
-					scratch.d.rowcompare_step.finfo = finfo;
-					scratch.d.rowcompare_step.fcinfo_data = fcinfo;
-					scratch.d.rowcompare_step.fn_addr = finfo->fn_addr;
+					scratch.rowcompare_step.finfo = finfo;
+					scratch.rowcompare_step.fcinfo_data = fcinfo;
+					scratch.rowcompare_step.fn_addr = finfo->fn_addr;
 					/* jump targets filled below */
-					scratch.d.rowcompare_step.jumpnull = -1;
-					scratch.d.rowcompare_step.jumpdone = -1;
+					scratch.rowcompare_step.jumpnull = -1;
+					scratch.rowcompare_step.jumpdone = -1;
 
 					ExprEvalPushStep(state, &scratch);
 					adjust_jumps = lappend_int(adjust_jumps,
@@ -2149,14 +2149,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				if (nopers == 0)
 				{
 					scratch.opcode = EEOP_CONST;
-					scratch.d.constval.value = Int32GetDatum(0);
-					scratch.d.constval.isnull = false;
+					scratch.constval.value = Int32GetDatum(0);
+					scratch.constval.isnull = false;
 					ExprEvalPushStep(state, &scratch);
 				}
 
 				/* Finally, examine the last comparison result */
 				scratch.opcode = EEOP_ROWCOMPARE_FINAL;
-				scratch.d.rowcompare_final.cmptype = rcexpr->cmptype;
+				scratch.rowcompare_final.cmptype = rcexpr->cmptype;
 				ExprEvalPushStep(state, &scratch);
 
 				/* adjust jump targets */
@@ -2165,13 +2165,13 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
 					Assert(as->opcode == EEOP_ROWCOMPARE_STEP);
-					Assert(as->d.rowcompare_step.jumpdone == -1);
-					Assert(as->d.rowcompare_step.jumpnull == -1);
+					Assert(as->rowcompare_step.jumpdone == -1);
+					Assert(as->rowcompare_step.jumpnull == -1);
 
 					/* jump to comparison evaluation */
-					as->d.rowcompare_step.jumpdone = state->steps_len - 1;
+					as->rowcompare_step.jumpdone = state->steps_len - 1;
 					/* jump to the following expression */
-					as->d.rowcompare_step.jumpnull = state->steps_len;
+					as->rowcompare_step.jumpnull = state->steps_len;
 				}
 
 				break;
@@ -2199,7 +2199,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 					/* if it's not null, skip to end of COALESCE expr */
 					scratch.opcode = EEOP_JUMP_IF_NOT_NULL;
-					scratch.d.jump.jumpdone = -1;	/* adjust later */
+					scratch.jump.jumpdone = -1; /* adjust later */
 					ExprEvalPushStep(state, &scratch);
 
 					adjust_jumps = lappend_int(adjust_jumps,
@@ -2218,8 +2218,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
 					Assert(as->opcode == EEOP_JUMP_IF_NOT_NULL);
-					Assert(as->d.jump.jumpdone == -1);
-					as->d.jump.jumpdone = state->steps_len;
+					Assert(as->jump.jumpdone == -1);
+					as->jump.jumpdone = state->steps_len;
 				}
 
 				break;
@@ -2261,15 +2261,15 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				scratch.opcode = EEOP_MINMAX;
 				/* allocate space to store arguments */
-				scratch.d.minmax.values =
+				scratch.minmax.values =
 					(Datum *) palloc(sizeof(Datum) * nelems);
-				scratch.d.minmax.nulls =
+				scratch.minmax.nulls =
 					(bool *) palloc(sizeof(bool) * nelems);
-				scratch.d.minmax.nelems = nelems;
+				scratch.minmax.nelems = nelems;
 
-				scratch.d.minmax.op = minmaxexpr->op;
-				scratch.d.minmax.finfo = finfo;
-				scratch.d.minmax.fcinfo_data = fcinfo;
+				scratch.minmax.op = minmaxexpr->op;
+				scratch.minmax.finfo = finfo;
+				scratch.minmax.fcinfo_data = fcinfo;
 
 				/* evaluate expressions into minmax->values/nulls */
 				off = 0;
@@ -2278,8 +2278,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					Expr	   *e = (Expr *) lfirst(lc);
 
 					ExecInitExprRec(e, state,
-									&scratch.d.minmax.values[off],
-									&scratch.d.minmax.nulls[off]);
+									&scratch.minmax.values[off],
+									&scratch.minmax.nulls[off]);
 					off++;
 				}
 
@@ -2293,7 +2293,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				SQLValueFunction *svf = (SQLValueFunction *) node;
 
 				scratch.opcode = EEOP_SQLVALUEFUNCTION;
-				scratch.d.sqlvaluefunction.svf = svf;
+				scratch.sqlvaluefunction.svf = svf;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -2308,33 +2308,33 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				ListCell   *arg;
 
 				scratch.opcode = EEOP_XMLEXPR;
-				scratch.d.xmlexpr.xexpr = xexpr;
+				scratch.xmlexpr.xexpr = xexpr;
 
 				/* allocate space for storing all the arguments */
 				if (nnamed)
 				{
-					scratch.d.xmlexpr.named_argvalue =
+					scratch.xmlexpr.named_argvalue =
 						(Datum *) palloc(sizeof(Datum) * nnamed);
-					scratch.d.xmlexpr.named_argnull =
+					scratch.xmlexpr.named_argnull =
 						(bool *) palloc(sizeof(bool) * nnamed);
 				}
 				else
 				{
-					scratch.d.xmlexpr.named_argvalue = NULL;
-					scratch.d.xmlexpr.named_argnull = NULL;
+					scratch.xmlexpr.named_argvalue = NULL;
+					scratch.xmlexpr.named_argnull = NULL;
 				}
 
 				if (nargs)
 				{
-					scratch.d.xmlexpr.argvalue =
+					scratch.xmlexpr.argvalue =
 						(Datum *) palloc(sizeof(Datum) * nargs);
-					scratch.d.xmlexpr.argnull =
+					scratch.xmlexpr.argnull =
 						(bool *) palloc(sizeof(bool) * nargs);
 				}
 				else
 				{
-					scratch.d.xmlexpr.argvalue = NULL;
-					scratch.d.xmlexpr.argnull = NULL;
+					scratch.xmlexpr.argvalue = NULL;
+					scratch.xmlexpr.argnull = NULL;
 				}
 
 				/* prepare argument execution */
@@ -2344,8 +2344,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					Expr	   *e = (Expr *) lfirst(arg);
 
 					ExecInitExprRec(e, state,
-									&scratch.d.xmlexpr.named_argvalue[off],
-									&scratch.d.xmlexpr.named_argnull[off]);
+									&scratch.xmlexpr.named_argvalue[off],
+									&scratch.xmlexpr.named_argnull[off]);
 					off++;
 				}
 
@@ -2355,8 +2355,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					Expr	   *e = (Expr *) lfirst(arg);
 
 					ExecInitExprRec(e, state,
-									&scratch.d.xmlexpr.argvalue[off],
-									&scratch.d.xmlexpr.argnull[off]);
+									&scratch.xmlexpr.argvalue[off],
+									&scratch.xmlexpr.argnull[off]);
 					off++;
 				}
 
@@ -2401,7 +2401,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 					jcstate = palloc0(sizeof(JsonConstructorExprState));
 
 					scratch.opcode = EEOP_JSON_CONSTRUCTOR;
-					scratch.d.json_constructor.jcstate = jcstate;
+					scratch.json_constructor.jcstate = jcstate;
 
 					jcstate->constructor = ctor;
 					jcstate->arg_values = (Datum *) palloc(sizeof(Datum) * nargs);
@@ -2481,7 +2481,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				ExecInitExprRec((Expr *) pred->expr, state, resv, resnull);
 
 				scratch.opcode = EEOP_IS_JSON;
-				scratch.d.is_json.pred = pred;
+				scratch.is_json.pred = pred;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -2528,7 +2528,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 						 (int) ntest->nulltesttype);
 				}
 				/* initialize cache in case it's a row test */
-				scratch.d.nulltest_row.rowcache.cacheptr = NULL;
+				scratch.nulltest_row.rowcache.cacheptr = NULL;
 
 				/* first evaluate argument into result variable */
 				ExecInitExprRec(ntest->arg, state,
@@ -2607,8 +2607,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				{
 					scratch.opcode = EEOP_DOMAIN_TESTVAL;
 					/* we share instruction union variant with case testval */
-					scratch.d.casetest.value = state->innermost_domainval;
-					scratch.d.casetest.isnull = state->innermost_domainnull;
+					scratch.casetest.value = state->innermost_domainval;
+					scratch.casetest.isnull = state->innermost_domainnull;
 				}
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -2626,8 +2626,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				NextValueExpr *nve = (NextValueExpr *) node;
 
 				scratch.opcode = EEOP_NEXTVALUEEXPR;
-				scratch.d.nextvalueexpr.seqid = nve->seqid;
-				scratch.d.nextvalueexpr.seqtypid = nve->typeId;
+				scratch.nextvalueexpr.seqid = nve->seqid;
+				scratch.nextvalueexpr.seqtypid = nve->typeId;
 
 				ExprEvalPushStep(state, &scratch);
 				break;
@@ -2640,9 +2640,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
 				/* Skip expression evaluation if OLD/NEW row doesn't exist */
 				scratch.opcode = EEOP_RETURNINGEXPR;
-				scratch.d.returningexpr.nullflag = rexpr->retold ?
+				scratch.returningexpr.nullflag = rexpr->retold ?
 					EEO_FLAG_OLD_IS_NULL : EEO_FLAG_NEW_IS_NULL;
-				scratch.d.returningexpr.jumpdone = -1;	/* set below */
+				scratch.returningexpr.jumpdone = -1;	/* set below */
 				ExprEvalPushStep(state, &scratch);
 				retstep = state->steps_len - 1;
 
@@ -2650,7 +2650,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
 				ExecInitExprRec(rexpr->retexpr, state, resv, resnull);
 
 				/* Jump target used if OLD/NEW row doesn't exist */
-				state->steps[retstep].d.returningexpr.jumpdone = state->steps_len;
+				state->steps[retstep].returningexpr.jumpdone = state->steps_len;
 
 				/* Update ExprState flags */
 				if (rexpr->retold)
@@ -2732,10 +2732,10 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
 							   FUNC_MAX_ARGS)));
 
 	/* Allocate function lookup data and parameter workspace for this call */
-	scratch->d.func.finfo = palloc0(sizeof(FmgrInfo));
-	scratch->d.func.fcinfo_data = palloc0(SizeForFunctionCallInfo(nargs));
-	flinfo = scratch->d.func.finfo;
-	fcinfo = scratch->d.func.fcinfo_data;
+	scratch->func.finfo = palloc0(sizeof(FmgrInfo));
+	scratch->func.fcinfo_data = palloc0(SizeForFunctionCallInfo(nargs));
+	flinfo = scratch->func.finfo;
+	fcinfo = scratch->func.fcinfo_data;
 
 	/* Set up the primary fmgr lookup information */
 	fmgr_info(funcid, flinfo);
@@ -2746,8 +2746,8 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
 							 nargs, inputcollid, NULL, NULL);
 
 	/* Keep extra copies of this info to save an indirection at runtime */
-	scratch->d.func.fn_addr = flinfo->fn_addr;
-	scratch->d.func.nargs = nargs;
+	scratch->func.fn_addr = flinfo->fn_addr;
+	scratch->func.nargs = nargs;
 
 	/* We only support non-set functions here */
 	if (flinfo->fn_retset)
@@ -2853,9 +2853,9 @@ ExecInitSubPlanExpr(SubPlan *subplan,
 						&state->resvalue, &state->resnull);
 
 		scratch.opcode = EEOP_PARAM_SET;
-		scratch.d.param.paramid = paramid;
+		scratch.param.paramid = paramid;
 		/* paramtype's not actually used, but we might as well fill it */
-		scratch.d.param.paramtype = exprType((Node *) arg);
+		scratch.param.paramtype = exprType((Node *) arg);
 		ExprEvalPushStep(state, &scratch);
 	}
 
@@ -2868,7 +2868,7 @@ ExecInitSubPlanExpr(SubPlan *subplan,
 	scratch.opcode = EEOP_SUBPLAN;
 	scratch.resvalue = resv;
 	scratch.resnull = resnull;
-	scratch.d.subplan.sstate = sstate;
+	scratch.subplan.sstate = sstate;
 
 	ExprEvalPushStep(state, &scratch);
 }
@@ -2909,50 +2909,50 @@ ExecPushExprSetupSteps(ExprState *state, ExprSetupInfo *info)
 	if (info->last_inner > 0)
 	{
 		scratch.opcode = EEOP_INNER_FETCHSOME;
-		scratch.d.fetch.last_var = info->last_inner;
-		scratch.d.fetch.fixed = false;
-		scratch.d.fetch.kind = NULL;
-		scratch.d.fetch.known_desc = NULL;
+		scratch.fetch.last_var = info->last_inner;
+		scratch.fetch.fixed = false;
+		scratch.fetch.kind = NULL;
+		scratch.fetch.known_desc = NULL;
 		if (ExecComputeSlotInfo(state, &scratch))
 			ExprEvalPushStep(state, &scratch);
 	}
 	if (info->last_outer > 0)
 	{
 		scratch.opcode = EEOP_OUTER_FETCHSOME;
-		scratch.d.fetch.last_var = info->last_outer;
-		scratch.d.fetch.fixed = false;
-		scratch.d.fetch.kind = NULL;
-		scratch.d.fetch.known_desc = NULL;
+		scratch.fetch.last_var = info->last_outer;
+		scratch.fetch.fixed = false;
+		scratch.fetch.kind = NULL;
+		scratch.fetch.known_desc = NULL;
 		if (ExecComputeSlotInfo(state, &scratch))
 			ExprEvalPushStep(state, &scratch);
 	}
 	if (info->last_scan > 0)
 	{
 		scratch.opcode = EEOP_SCAN_FETCHSOME;
-		scratch.d.fetch.last_var = info->last_scan;
-		scratch.d.fetch.fixed = false;
-		scratch.d.fetch.kind = NULL;
-		scratch.d.fetch.known_desc = NULL;
+		scratch.fetch.last_var = info->last_scan;
+		scratch.fetch.fixed = false;
+		scratch.fetch.kind = NULL;
+		scratch.fetch.known_desc = NULL;
 		if (ExecComputeSlotInfo(state, &scratch))
 			ExprEvalPushStep(state, &scratch);
 	}
 	if (info->last_old > 0)
 	{
 		scratch.opcode = EEOP_OLD_FETCHSOME;
-		scratch.d.fetch.last_var = info->last_old;
-		scratch.d.fetch.fixed = false;
-		scratch.d.fetch.kind = NULL;
-		scratch.d.fetch.known_desc = NULL;
+		scratch.fetch.last_var = info->last_old;
+		scratch.fetch.fixed = false;
+		scratch.fetch.kind = NULL;
+		scratch.fetch.known_desc = NULL;
 		if (ExecComputeSlotInfo(state, &scratch))
 			ExprEvalPushStep(state, &scratch);
 	}
 	if (info->last_new > 0)
 	{
 		scratch.opcode = EEOP_NEW_FETCHSOME;
-		scratch.d.fetch.last_var = info->last_new;
-		scratch.d.fetch.fixed = false;
-		scratch.d.fetch.kind = NULL;
-		scratch.d.fetch.known_desc = NULL;
+		scratch.fetch.last_var = info->last_new;
+		scratch.fetch.fixed = false;
+		scratch.fetch.kind = NULL;
+		scratch.fetch.known_desc = NULL;
 		if (ExecComputeSlotInfo(state, &scratch))
 			ExprEvalPushStep(state, &scratch);
 	}
@@ -3073,11 +3073,11 @@ ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
 		   opcode == EEOP_OLD_FETCHSOME ||
 		   opcode == EEOP_NEW_FETCHSOME);
 
-	if (op->d.fetch.known_desc != NULL)
+	if (op->fetch.known_desc != NULL)
 	{
-		desc = op->d.fetch.known_desc;
-		tts_ops = op->d.fetch.kind;
-		isfixed = op->d.fetch.kind != NULL;
+		desc = op->fetch.known_desc;
+		tts_ops = op->fetch.kind;
+		isfixed = op->fetch.kind != NULL;
 	}
 	else if (!parent)
 	{
@@ -3138,19 +3138,19 @@ ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
 
 	if (isfixed && desc != NULL && tts_ops != NULL)
 	{
-		op->d.fetch.fixed = true;
-		op->d.fetch.kind = tts_ops;
-		op->d.fetch.known_desc = desc;
+		op->fetch.fixed = true;
+		op->fetch.kind = tts_ops;
+		op->fetch.known_desc = desc;
 	}
 	else
 	{
-		op->d.fetch.fixed = false;
-		op->d.fetch.kind = NULL;
-		op->d.fetch.known_desc = NULL;
+		op->fetch.fixed = false;
+		op->fetch.kind = NULL;
+		op->fetch.known_desc = NULL;
 	}
 
 	/* if the slot is known to always virtual we never need to deform */
-	if (op->d.fetch.fixed && op->d.fetch.kind == &TTSOpsVirtual)
+	if (op->fetch.fixed && op->fetch.kind == &TTSOpsVirtual)
 		return false;
 
 	return true;
@@ -3167,11 +3167,11 @@ ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
 
 	/* fill in all but the target */
 	scratch->opcode = EEOP_WHOLEROW;
-	scratch->d.wholerow.var = variable;
-	scratch->d.wholerow.first = true;
-	scratch->d.wholerow.slow = false;
-	scratch->d.wholerow.tupdesc = NULL; /* filled at runtime */
-	scratch->d.wholerow.junkFilter = NULL;
+	scratch->wholerow.var = variable;
+	scratch->wholerow.first = true;
+	scratch->wholerow.slow = false;
+	scratch->wholerow.tupdesc = NULL;	/* filled at runtime */
+	scratch->wholerow.junkFilter = NULL;
 
 	/* update ExprState flags if Var refers to OLD/NEW */
 	if (variable->varreturningtype == VAR_RETURNING_OLD)
@@ -3227,7 +3227,7 @@ ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
 			/* If so, build the junkfilter now */
 			if (junk_filter_needed)
 			{
-				scratch->d.wholerow.junkFilter =
+				scratch->wholerow.junkFilter =
 					ExecInitJunkFilter(subplan->plan->targetlist,
 									   ExecInitExtraTupleSlot(parent->state, NULL,
 															  &TTSOpsVirtual));
@@ -3314,7 +3314,7 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
 	if (!isAssignment && sbsroutines->fetch_strict)
 	{
 		scratch->opcode = EEOP_JUMP_IF_NULL;
-		scratch->d.jump.jumpdone = -1;	/* adjust later */
+		scratch->jump.jumpdone = -1;	/* adjust later */
 		ExprEvalPushStep(state, scratch);
 		adjust_jumps = lappend_int(adjust_jumps,
 								   state->steps_len - 1);
@@ -3370,9 +3370,9 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
 	if (methods.sbs_check_subscripts)
 	{
 		scratch->opcode = EEOP_SBSREF_SUBSCRIPTS;
-		scratch->d.sbsref_subscript.subscriptfunc = methods.sbs_check_subscripts;
-		scratch->d.sbsref_subscript.state = sbsrefstate;
-		scratch->d.sbsref_subscript.jumpdone = -1;	/* adjust later */
+		scratch->sbsref_subscript.subscriptfunc = methods.sbs_check_subscripts;
+		scratch->sbsref_subscript.state = sbsrefstate;
+		scratch->sbsref_subscript.jumpdone = -1;	/* adjust later */
 		ExprEvalPushStep(state, scratch);
 		adjust_jumps = lappend_int(adjust_jumps,
 								   state->steps_len - 1);
@@ -3412,8 +3412,8 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
 						 errmsg("type %s does not support subscripted assignment",
 								format_type_be(sbsref->refcontainertype))));
 			scratch->opcode = EEOP_SBSREF_OLD;
-			scratch->d.sbsref.subscriptfunc = methods.sbs_fetch_old;
-			scratch->d.sbsref.state = sbsrefstate;
+			scratch->sbsref.subscriptfunc = methods.sbs_fetch_old;
+			scratch->sbsref.state = sbsrefstate;
 			ExprEvalPushStep(state, scratch);
 		}
 
@@ -3432,16 +3432,16 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
 
 		/* and perform the assignment */
 		scratch->opcode = EEOP_SBSREF_ASSIGN;
-		scratch->d.sbsref.subscriptfunc = methods.sbs_assign;
-		scratch->d.sbsref.state = sbsrefstate;
+		scratch->sbsref.subscriptfunc = methods.sbs_assign;
+		scratch->sbsref.state = sbsrefstate;
 		ExprEvalPushStep(state, scratch);
 	}
 	else
 	{
 		/* array fetch is much simpler */
 		scratch->opcode = EEOP_SBSREF_FETCH;
-		scratch->d.sbsref.subscriptfunc = methods.sbs_fetch;
-		scratch->d.sbsref.state = sbsrefstate;
+		scratch->sbsref.subscriptfunc = methods.sbs_fetch;
+		scratch->sbsref.state = sbsrefstate;
 		ExprEvalPushStep(state, scratch);
 	}
 
@@ -3452,14 +3452,14 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
 
 		if (as->opcode == EEOP_SBSREF_SUBSCRIPTS)
 		{
-			Assert(as->d.sbsref_subscript.jumpdone == -1);
-			as->d.sbsref_subscript.jumpdone = state->steps_len;
+			Assert(as->sbsref_subscript.jumpdone == -1);
+			as->sbsref_subscript.jumpdone = state->steps_len;
 		}
 		else
 		{
 			Assert(as->opcode == EEOP_JUMP_IF_NULL);
-			Assert(as->d.jump.jumpdone == -1);
-			as->d.jump.jumpdone = state->steps_len;
+			Assert(as->jump.jumpdone == -1);
+			as->jump.jumpdone = state->steps_len;
 		}
 	}
 }
@@ -3527,11 +3527,11 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
 	bool	   *domainnull = NULL;
 	ListCell   *l;
 
-	scratch->d.domaincheck.resulttype = ctest->resulttype;
+	scratch->domaincheck.resulttype = ctest->resulttype;
 	/* we'll allocate workspace only if needed */
-	scratch->d.domaincheck.checkvalue = NULL;
-	scratch->d.domaincheck.checknull = NULL;
-	scratch->d.domaincheck.escontext = state->escontext;
+	scratch->domaincheck.checkvalue = NULL;
+	scratch->domaincheck.checknull = NULL;
+	scratch->domaincheck.escontext = state->escontext;
 
 	/*
 	 * Evaluate argument - it's fine to directly store it into resv/resnull,
@@ -3575,7 +3575,7 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
 		Datum	   *save_innermost_domainval;
 		bool	   *save_innermost_domainnull;
 
-		scratch->d.domaincheck.constraintname = con->name;
+		scratch->domaincheck.constraintname = con->name;
 
 		switch (con->constrainttype)
 		{
@@ -3585,11 +3585,11 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
 				break;
 			case DOM_CONSTRAINT_CHECK:
 				/* Allocate workspace for CHECK output if we didn't yet */
-				if (scratch->d.domaincheck.checkvalue == NULL)
+				if (scratch->domaincheck.checkvalue == NULL)
 				{
-					scratch->d.domaincheck.checkvalue =
+					scratch->domaincheck.checkvalue =
 						(Datum *) palloc(sizeof(Datum));
-					scratch->d.domaincheck.checknull =
+					scratch->domaincheck.checknull =
 						(bool *) palloc(sizeof(bool));
 				}
 
@@ -3615,8 +3615,8 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
 						scratch2.opcode = EEOP_MAKE_READONLY;
 						scratch2.resvalue = domainval;
 						scratch2.resnull = domainnull;
-						scratch2.d.make_readonly.value = resv;
-						scratch2.d.make_readonly.isnull = resnull;
+						scratch2.make_readonly.value = resv;
+						scratch2.make_readonly.isnull = resnull;
 						ExprEvalPushStep(state, &scratch2);
 					}
 					else
@@ -3640,8 +3640,8 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
 
 				/* evaluate check expression value */
 				ExecInitExprRec(con->check_expr, state,
-								scratch->d.domaincheck.checkvalue,
-								scratch->d.domaincheck.checknull);
+								scratch->domaincheck.checkvalue,
+								scratch->domaincheck.checknull);
 
 				state->innermost_domainval = save_innermost_domainval;
 				state->innermost_domainnull = save_innermost_domainnull;
@@ -3736,7 +3736,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
 							&state->resvalue, &state->resnull);
 			/* and jump out if false */
 			scratch.opcode = EEOP_JUMP_IF_NOT_TRUE;
-			scratch.d.jump.jumpdone = -1;	/* adjust later */
+			scratch.jump.jumpdone = -1; /* adjust later */
 			ExprEvalPushStep(state, &scratch);
 			adjust_bailout = lappend_int(adjust_bailout,
 										 state->steps_len - 1);
@@ -3797,8 +3797,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
 				else
 					scratch.opcode = EEOP_AGG_DESERIALIZE;
 
-				scratch.d.agg_deserialize.fcinfo_data = ds_fcinfo;
-				scratch.d.agg_deserialize.jumpnull = -1;	/* adjust later */
+				scratch.agg_deserialize.fcinfo_data = ds_fcinfo;
+				scratch.agg_deserialize.jumpnull = -1;	/* adjust later */
 				scratch.resvalue = &trans_fcinfo->args[argno + 1].value;
 				scratch.resnull = &trans_fcinfo->args[argno + 1].isnull;
 
@@ -3904,10 +3904,10 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
 				scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1;
 			else
 				scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK_ARGS;
-			scratch.d.agg_strict_input_check.nulls = strictnulls;
-			scratch.d.agg_strict_input_check.args = strictargs;
-			scratch.d.agg_strict_input_check.jumpnull = -1; /* adjust later */
-			scratch.d.agg_strict_input_check.nargs = pertrans->numTransInputs;
+			scratch.agg_strict_input_check.nulls = strictnulls;
+			scratch.agg_strict_input_check.args = strictargs;
+			scratch.agg_strict_input_check.jumpnull = -1;	/* adjust later */
+			scratch.agg_strict_input_check.nargs = pertrans->numTransInputs;
 			ExprEvalPushStep(state, &scratch);
 			adjust_bailout = lappend_int(adjust_bailout,
 										 state->steps_len - 1);
@@ -3921,8 +3921,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
 			else
 				scratch.opcode = EEOP_AGG_PRESORTED_DISTINCT_SINGLE;
 
-			scratch.d.agg_presorted_distinctcheck.pertrans = pertrans;
-			scratch.d.agg_presorted_distinctcheck.jumpdistinct = -1;	/* adjust later */
+			scratch.agg_presorted_distinctcheck.pertrans = pertrans;
+			scratch.agg_presorted_distinctcheck.jumpdistinct = -1;	/* adjust later */
 			ExprEvalPushStep(state, &scratch);
 			adjust_bailout = lappend_int(adjust_bailout,
 										 state->steps_len - 1);
@@ -3974,26 +3974,26 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
 
 			if (as->opcode == EEOP_JUMP_IF_NOT_TRUE)
 			{
-				Assert(as->d.jump.jumpdone == -1);
-				as->d.jump.jumpdone = state->steps_len;
+				Assert(as->jump.jumpdone == -1);
+				as->jump.jumpdone = state->steps_len;
 			}
 			else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_ARGS ||
 					 as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1 ||
 					 as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
 			{
-				Assert(as->d.agg_strict_input_check.jumpnull == -1);
-				as->d.agg_strict_input_check.jumpnull = state->steps_len;
+				Assert(as->agg_strict_input_check.jumpnull == -1);
+				as->agg_strict_input_check.jumpnull = state->steps_len;
 			}
 			else if (as->opcode == EEOP_AGG_STRICT_DESERIALIZE)
 			{
-				Assert(as->d.agg_deserialize.jumpnull == -1);
-				as->d.agg_deserialize.jumpnull = state->steps_len;
+				Assert(as->agg_deserialize.jumpnull == -1);
+				as->agg_deserialize.jumpnull = state->steps_len;
 			}
 			else if (as->opcode == EEOP_AGG_PRESORTED_DISTINCT_SINGLE ||
 					 as->opcode == EEOP_AGG_PRESORTED_DISTINCT_MULTI)
 			{
-				Assert(as->d.agg_presorted_distinctcheck.jumpdistinct == -1);
-				as->d.agg_presorted_distinctcheck.jumpdistinct = state->steps_len;
+				Assert(as->agg_presorted_distinctcheck.jumpdistinct == -1);
+				as->agg_presorted_distinctcheck.jumpdistinct = state->steps_len;
 			}
 			else
 				Assert(false);
@@ -4034,9 +4034,9 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
 	if (nullcheck)
 	{
 		scratch->opcode = EEOP_AGG_PLAIN_PERGROUP_NULLCHECK;
-		scratch->d.agg_plain_pergroup_nullcheck.setoff = setoff;
+		scratch->agg_plain_pergroup_nullcheck.setoff = setoff;
 		/* adjust later */
-		scratch->d.agg_plain_pergroup_nullcheck.jumpnull = -1;
+		scratch->agg_plain_pergroup_nullcheck.jumpnull = -1;
 		ExprEvalPushStep(state, scratch);
 		adjust_jumpnull = state->steps_len - 1;
 	}
@@ -4103,11 +4103,11 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
 	else
 		scratch->opcode = EEOP_AGG_ORDERED_TRANS_TUPLE;
 
-	scratch->d.agg_trans.pertrans = pertrans;
-	scratch->d.agg_trans.setno = setno;
-	scratch->d.agg_trans.setoff = setoff;
-	scratch->d.agg_trans.transno = transno;
-	scratch->d.agg_trans.aggcontext = aggcontext;
+	scratch->agg_trans.pertrans = pertrans;
+	scratch->agg_trans.setno = setno;
+	scratch->agg_trans.setoff = setoff;
+	scratch->agg_trans.transno = transno;
+	scratch->agg_trans.aggcontext = aggcontext;
 	ExprEvalPushStep(state, scratch);
 
 	/* fix up jumpnull */
@@ -4116,8 +4116,8 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
 		ExprEvalStep *as = &state->steps[adjust_jumpnull];
 
 		Assert(as->opcode == EEOP_AGG_PLAIN_PERGROUP_NULLCHECK);
-		Assert(as->d.agg_plain_pergroup_nullcheck.jumpnull == -1);
-		as->d.agg_plain_pergroup_nullcheck.jumpnull = state->steps_len;
+		Assert(as->agg_plain_pergroup_nullcheck.jumpnull == -1);
+		as->agg_plain_pergroup_nullcheck.jumpnull = state->steps_len;
 	}
 }
 
@@ -4166,10 +4166,10 @@ ExecBuildHash32FromAttrs(TupleDesc desc, const TupleTableSlotOps *ops,
 		last_attnum = Max(last_attnum, keyColIdx[i]);
 
 	scratch.opcode = EEOP_INNER_FETCHSOME;
-	scratch.d.fetch.last_var = last_attnum;
-	scratch.d.fetch.fixed = false;
-	scratch.d.fetch.kind = ops;
-	scratch.d.fetch.known_desc = desc;
+	scratch.fetch.last_var = last_attnum;
+	scratch.fetch.fixed = false;
+	scratch.fetch.kind = ops;
+	scratch.fetch.known_desc = desc;
 	if (ExecComputeSlotInfo(state, &scratch))
 		ExprEvalPushStep(state, &scratch);
 
@@ -4190,7 +4190,7 @@ ExecBuildHash32FromAttrs(TupleDesc desc, const TupleTableSlotOps *ops,
 		 * columns to hash, store it in the ExprState's result field.
 		 */
 		scratch.opcode = EEOP_HASHDATUM_SET_INITVAL;
-		scratch.d.hashdatum_initvalue.init_value = UInt32GetDatum(init_value);
+		scratch.hashdatum_initvalue.init_value = UInt32GetDatum(init_value);
 		scratch.resvalue = numCols > 0 ? &iresult->value : &state->resvalue;
 		scratch.resnull = numCols > 0 ? &iresult->isnull : &state->resnull;
 
@@ -4223,9 +4223,9 @@ ExecBuildHash32FromAttrs(TupleDesc desc, const TupleTableSlotOps *ops,
 		scratch.opcode = EEOP_INNER_VAR;
 		scratch.resvalue = &fcinfo->args[0].value;
 		scratch.resnull = &fcinfo->args[0].isnull;
-		scratch.d.var.attnum = attnum;
-		scratch.d.var.vartype = TupleDescAttr(desc, attnum)->atttypid;
-		scratch.d.var.varreturningtype = VAR_RETURNING_DEFAULT;
+		scratch.var.attnum = attnum;
+		scratch.var.vartype = TupleDescAttr(desc, attnum)->atttypid;
+		scratch.var.varreturningtype = VAR_RETURNING_DEFAULT;
 
 		ExprEvalPushStep(state, &scratch);
 
@@ -4254,12 +4254,12 @@ ExecBuildHash32FromAttrs(TupleDesc desc, const TupleTableSlotOps *ops,
 		 * NEXT32 opcodes need to look at the intermediate result.  We might
 		 * as well just set this for all ops.  FIRSTs won't look at it.
 		 */
-		scratch.d.hashdatum.iresult = iresult;
+		scratch.hashdatum.iresult = iresult;
 
-		scratch.d.hashdatum.finfo = finfo;
-		scratch.d.hashdatum.fcinfo_data = fcinfo;
-		scratch.d.hashdatum.fn_addr = finfo->fn_addr;
-		scratch.d.hashdatum.jumpdone = -1;
+		scratch.hashdatum.finfo = finfo;
+		scratch.hashdatum.fcinfo_data = fcinfo;
+		scratch.hashdatum.fn_addr = finfo->fn_addr;
+		scratch.hashdatum.jumpdone = -1;
 
 		ExprEvalPushStep(state, &scratch);
 
@@ -4345,7 +4345,7 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
 		 * to hash, store it in the ExprState's result field.
 		 */
 		scratch.opcode = EEOP_HASHDATUM_SET_INITVAL;
-		scratch.d.hashdatum_initvalue.init_value = UInt32GetDatum(init_value);
+		scratch.hashdatum_initvalue.init_value = UInt32GetDatum(init_value);
 		scratch.resvalue = num_exprs > 0 ? &iresult->value : &state->resvalue;
 		scratch.resnull = num_exprs > 0 ? &iresult->isnull : &state->resnull;
 
@@ -4404,17 +4404,17 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
 		 * NEXT32 opcodes need to look at the intermediate result.  We might
 		 * as well just set this for all ops.  FIRSTs won't look at it.
 		 */
-		scratch.d.hashdatum.iresult = iresult;
+		scratch.hashdatum.iresult = iresult;
 
 		/* Initialize function call parameter structure too */
 		InitFunctionCallInfoData(*fcinfo, finfo, 1, inputcollid, NULL, NULL);
 
-		scratch.d.hashdatum.finfo = finfo;
-		scratch.d.hashdatum.fcinfo_data = fcinfo;
-		scratch.d.hashdatum.fn_addr = finfo->fn_addr;
+		scratch.hashdatum.finfo = finfo;
+		scratch.hashdatum.fcinfo_data = fcinfo;
+		scratch.hashdatum.fn_addr = finfo->fn_addr;
 
 		scratch.opcode = opstrict[i] && !keep_nulls ? strict_opcode : opcode;
-		scratch.d.hashdatum.jumpdone = -1;
+		scratch.hashdatum.jumpdone = -1;
 
 		ExprEvalPushStep(state, &scratch);
 		adjust_jumps = lappend_int(adjust_jumps, state->steps_len - 1);
@@ -4436,8 +4436,8 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
 			   as->opcode == EEOP_HASHDATUM_FIRST_STRICT ||
 			   as->opcode == EEOP_HASHDATUM_NEXT32 ||
 			   as->opcode == EEOP_HASHDATUM_NEXT32_STRICT);
-		Assert(as->d.hashdatum.jumpdone == -1);
-		as->d.hashdatum.jumpdone = state->steps_len;
+		Assert(as->hashdatum.jumpdone == -1);
+		as->hashdatum.jumpdone = state->steps_len;
 	}
 
 	scratch.resvalue = NULL;
@@ -4502,18 +4502,18 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
 
 	/* push deform steps */
 	scratch.opcode = EEOP_INNER_FETCHSOME;
-	scratch.d.fetch.last_var = maxatt;
-	scratch.d.fetch.fixed = false;
-	scratch.d.fetch.known_desc = ldesc;
-	scratch.d.fetch.kind = lops;
+	scratch.fetch.last_var = maxatt;
+	scratch.fetch.fixed = false;
+	scratch.fetch.known_desc = ldesc;
+	scratch.fetch.kind = lops;
 	if (ExecComputeSlotInfo(state, &scratch))
 		ExprEvalPushStep(state, &scratch);
 
 	scratch.opcode = EEOP_OUTER_FETCHSOME;
-	scratch.d.fetch.last_var = maxatt;
-	scratch.d.fetch.fixed = false;
-	scratch.d.fetch.known_desc = rdesc;
-	scratch.d.fetch.kind = rops;
+	scratch.fetch.last_var = maxatt;
+	scratch.fetch.fixed = false;
+	scratch.fetch.known_desc = rdesc;
+	scratch.fetch.kind = rops;
 	if (ExecComputeSlotInfo(state, &scratch))
 		ExprEvalPushStep(state, &scratch);
 
@@ -4549,35 +4549,35 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
 
 		/* left arg */
 		scratch.opcode = EEOP_INNER_VAR;
-		scratch.d.var.attnum = attno - 1;
-		scratch.d.var.vartype = latt->atttypid;
-		scratch.d.var.varreturningtype = VAR_RETURNING_DEFAULT;
+		scratch.var.attnum = attno - 1;
+		scratch.var.vartype = latt->atttypid;
+		scratch.var.varreturningtype = VAR_RETURNING_DEFAULT;
 		scratch.resvalue = &fcinfo->args[0].value;
 		scratch.resnull = &fcinfo->args[0].isnull;
 		ExprEvalPushStep(state, &scratch);
 
 		/* right arg */
 		scratch.opcode = EEOP_OUTER_VAR;
-		scratch.d.var.attnum = attno - 1;
-		scratch.d.var.vartype = ratt->atttypid;
-		scratch.d.var.varreturningtype = VAR_RETURNING_DEFAULT;
+		scratch.var.attnum = attno - 1;
+		scratch.var.vartype = ratt->atttypid;
+		scratch.var.varreturningtype = VAR_RETURNING_DEFAULT;
 		scratch.resvalue = &fcinfo->args[1].value;
 		scratch.resnull = &fcinfo->args[1].isnull;
 		ExprEvalPushStep(state, &scratch);
 
 		/* evaluate distinctness */
 		scratch.opcode = EEOP_NOT_DISTINCT;
-		scratch.d.func.finfo = finfo;
-		scratch.d.func.fcinfo_data = fcinfo;
-		scratch.d.func.fn_addr = finfo->fn_addr;
-		scratch.d.func.nargs = 2;
+		scratch.func.finfo = finfo;
+		scratch.func.fcinfo_data = fcinfo;
+		scratch.func.fn_addr = finfo->fn_addr;
+		scratch.func.nargs = 2;
 		scratch.resvalue = &state->resvalue;
 		scratch.resnull = &state->resnull;
 		ExprEvalPushStep(state, &scratch);
 
 		/* then emit EEOP_QUAL to detect if result is false (or null) */
 		scratch.opcode = EEOP_QUAL;
-		scratch.d.qualexpr.jumpdone = -1;
+		scratch.qualexpr.jumpdone = -1;
 		scratch.resvalue = &state->resvalue;
 		scratch.resnull = &state->resnull;
 		ExprEvalPushStep(state, &scratch);
@@ -4591,8 +4591,8 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
 		Assert(as->opcode == EEOP_QUAL);
-		Assert(as->d.qualexpr.jumpdone == -1);
-		as->d.qualexpr.jumpdone = state->steps_len;
+		Assert(as->qualexpr.jumpdone == -1);
+		as->qualexpr.jumpdone = state->steps_len;
 	}
 
 	scratch.resvalue = NULL;
@@ -4644,18 +4644,18 @@ ExecBuildParamSetEqual(TupleDesc desc,
 
 	/* push deform steps */
 	scratch.opcode = EEOP_INNER_FETCHSOME;
-	scratch.d.fetch.last_var = maxatt;
-	scratch.d.fetch.fixed = false;
-	scratch.d.fetch.known_desc = desc;
-	scratch.d.fetch.kind = lops;
+	scratch.fetch.last_var = maxatt;
+	scratch.fetch.fixed = false;
+	scratch.fetch.known_desc = desc;
+	scratch.fetch.kind = lops;
 	if (ExecComputeSlotInfo(state, &scratch))
 		ExprEvalPushStep(state, &scratch);
 
 	scratch.opcode = EEOP_OUTER_FETCHSOME;
-	scratch.d.fetch.last_var = maxatt;
-	scratch.d.fetch.fixed = false;
-	scratch.d.fetch.known_desc = desc;
-	scratch.d.fetch.kind = rops;
+	scratch.fetch.last_var = maxatt;
+	scratch.fetch.fixed = false;
+	scratch.fetch.known_desc = desc;
+	scratch.fetch.kind = rops;
 	if (ExecComputeSlotInfo(state, &scratch))
 		ExprEvalPushStep(state, &scratch);
 
@@ -4685,35 +4685,35 @@ ExecBuildParamSetEqual(TupleDesc desc,
 
 		/* left arg */
 		scratch.opcode = EEOP_INNER_VAR;
-		scratch.d.var.attnum = attno;
-		scratch.d.var.vartype = att->atttypid;
-		scratch.d.var.varreturningtype = VAR_RETURNING_DEFAULT;
+		scratch.var.attnum = attno;
+		scratch.var.vartype = att->atttypid;
+		scratch.var.varreturningtype = VAR_RETURNING_DEFAULT;
 		scratch.resvalue = &fcinfo->args[0].value;
 		scratch.resnull = &fcinfo->args[0].isnull;
 		ExprEvalPushStep(state, &scratch);
 
 		/* right arg */
 		scratch.opcode = EEOP_OUTER_VAR;
-		scratch.d.var.attnum = attno;
-		scratch.d.var.vartype = att->atttypid;
-		scratch.d.var.varreturningtype = VAR_RETURNING_DEFAULT;
+		scratch.var.attnum = attno;
+		scratch.var.vartype = att->atttypid;
+		scratch.var.varreturningtype = VAR_RETURNING_DEFAULT;
 		scratch.resvalue = &fcinfo->args[1].value;
 		scratch.resnull = &fcinfo->args[1].isnull;
 		ExprEvalPushStep(state, &scratch);
 
 		/* evaluate distinctness */
 		scratch.opcode = EEOP_NOT_DISTINCT;
-		scratch.d.func.finfo = finfo;
-		scratch.d.func.fcinfo_data = fcinfo;
-		scratch.d.func.fn_addr = finfo->fn_addr;
-		scratch.d.func.nargs = 2;
+		scratch.func.finfo = finfo;
+		scratch.func.fcinfo_data = fcinfo;
+		scratch.func.fn_addr = finfo->fn_addr;
+		scratch.func.nargs = 2;
 		scratch.resvalue = &state->resvalue;
 		scratch.resnull = &state->resnull;
 		ExprEvalPushStep(state, &scratch);
 
 		/* then emit EEOP_QUAL to detect if result is false (or null) */
 		scratch.opcode = EEOP_QUAL;
-		scratch.d.qualexpr.jumpdone = -1;
+		scratch.qualexpr.jumpdone = -1;
 		scratch.resvalue = &state->resvalue;
 		scratch.resnull = &state->resnull;
 		ExprEvalPushStep(state, &scratch);
@@ -4727,8 +4727,8 @@ ExecBuildParamSetEqual(TupleDesc desc,
 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
 		Assert(as->opcode == EEOP_QUAL);
-		Assert(as->d.qualexpr.jumpdone == -1);
-		as->d.qualexpr.jumpdone = state->steps_len;
+		Assert(as->qualexpr.jumpdone == -1);
+		as->qualexpr.jumpdone = state->steps_len;
 	}
 
 	scratch.resvalue = NULL;
@@ -4775,7 +4775,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 	jumps_return_null = lappend_int(jumps_return_null, state->steps_len);
 	scratch->opcode = EEOP_JUMP_IF_NULL;
 	scratch->resnull = &jsestate->formatted_expr.isnull;
-	scratch->d.jump.jumpdone = -1;	/* set below */
+	scratch->jump.jumpdone = -1;	/* set below */
 	ExprEvalPushStep(state, scratch);
 
 	/*
@@ -4790,7 +4790,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 	jumps_return_null = lappend_int(jumps_return_null, state->steps_len);
 	scratch->opcode = EEOP_JUMP_IF_NULL;
 	scratch->resnull = &jsestate->pathspec.isnull;
-	scratch->d.jump.jumpdone = -1;	/* set below */
+	scratch->jump.jumpdone = -1;	/* set below */
 	ExprEvalPushStep(state, scratch);
 
 	/* Steps to compute PASSING args. */
@@ -4816,7 +4816,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 	scratch->opcode = EEOP_JSONEXPR_PATH;
 	scratch->resvalue = resv;
 	scratch->resnull = resnull;
-	scratch->d.jsonexpr.jsestate = jsestate;
+	scratch->jsonexpr.jsestate = jsestate;
 	ExprEvalPushStep(state, scratch);
 
 	/*
@@ -4828,13 +4828,13 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 	{
 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
-		as->d.jump.jumpdone = state->steps_len;
+		as->jump.jumpdone = state->steps_len;
 	}
 	scratch->opcode = EEOP_CONST;
 	scratch->resvalue = resv;
 	scratch->resnull = resnull;
-	scratch->d.constval.value = (Datum) 0;
-	scratch->d.constval.isnull = true;
+	scratch->constval.value = (Datum) 0;
+	scratch->constval.isnull = true;
 	ExprEvalPushStep(state, scratch);
 
 	escontext = jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR ?
@@ -4901,7 +4901,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 	if (jsestate->jump_eval_coercion >= 0 && escontext != NULL)
 	{
 		scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH;
-		scratch->d.jsonexpr.jsestate = jsestate;
+		scratch->jsonexpr.jsestate = jsestate;
 		ExprEvalPushStep(state, scratch);
 	}
 
@@ -4933,7 +4933,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 		scratch->opcode = EEOP_JUMP_IF_NOT_TRUE;
 		scratch->resvalue = &jsestate->error.value;
 		scratch->resnull = &jsestate->error.isnull;
-		scratch->d.jump.jumpdone = -1;	/* set below */
+		scratch->jump.jumpdone = -1;	/* set below */
 		ExprEvalPushStep(state, scratch);
 
 		/*
@@ -4963,14 +4963,14 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 			scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH;
 			scratch->resvalue = resv;
 			scratch->resnull = resnull;
-			scratch->d.jsonexpr.jsestate = jsestate;
+			scratch->jsonexpr.jsestate = jsestate;
 			ExprEvalPushStep(state, scratch);
 		}
 
 		/* JUMP to end to skip the ON EMPTY steps added below. */
 		jumps_to_end = lappend_int(jumps_to_end, state->steps_len);
 		scratch->opcode = EEOP_JUMP;
-		scratch->d.jump.jumpdone = -1;
+		scratch->jump.jumpdone = -1;
 		ExprEvalPushStep(state, scratch);
 	}
 
@@ -4996,7 +4996,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 		scratch->opcode = EEOP_JUMP_IF_NOT_TRUE;
 		scratch->resvalue = &jsestate->empty.value;
 		scratch->resnull = &jsestate->empty.isnull;
-		scratch->d.jump.jumpdone = -1;	/* set below */
+		scratch->jump.jumpdone = -1;	/* set below */
 		ExprEvalPushStep(state, scratch);
 
 		/*
@@ -5027,7 +5027,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 			scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH;
 			scratch->resvalue = resv;
 			scratch->resnull = resnull;
-			scratch->d.jsonexpr.jsestate = jsestate;
+			scratch->jsonexpr.jsestate = jsestate;
 			ExprEvalPushStep(state, scratch);
 		}
 	}
@@ -5036,7 +5036,7 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
 	{
 		ExprEvalStep *as = &state->steps[lfirst_int(lc)];
 
-		as->d.jump.jumpdone = state->steps_len;
+		as->jump.jumpdone = state->steps_len;
 	}
 
 	jsestate->jump_end = state->steps_len;
@@ -5058,15 +5058,15 @@ ExecInitJsonCoercion(ExprState *state, JsonReturning *returning,
 	scratch.opcode = EEOP_JSONEXPR_COERCION;
 	scratch.resvalue = resv;
 	scratch.resnull = resnull;
-	scratch.d.jsonexpr_coercion.targettype = returning->typid;
-	scratch.d.jsonexpr_coercion.targettypmod = returning->typmod;
-	scratch.d.jsonexpr_coercion.json_coercion_cache = NULL;
-	scratch.d.jsonexpr_coercion.escontext = escontext;
-	scratch.d.jsonexpr_coercion.omit_quotes = omit_quotes;
-	scratch.d.jsonexpr_coercion.exists_coerce = exists_coerce;
-	scratch.d.jsonexpr_coercion.exists_cast_to_int = exists_coerce &&
+	scratch.jsonexpr_coercion.targettype = returning->typid;
+	scratch.jsonexpr_coercion.targettypmod = returning->typmod;
+	scratch.jsonexpr_coercion.json_coercion_cache = NULL;
+	scratch.jsonexpr_coercion.escontext = escontext;
+	scratch.jsonexpr_coercion.omit_quotes = omit_quotes;
+	scratch.jsonexpr_coercion.exists_coerce = exists_coerce;
+	scratch.jsonexpr_coercion.exists_cast_to_int = exists_coerce &&
 		getBaseType(returning->typid) == INT4OID;
-	scratch.d.jsonexpr_coercion.exists_check_domain = exists_coerce &&
+	scratch.jsonexpr_coercion.exists_check_domain = exists_coerce &&
 		DomainHasConstraints(returning->typid);
 	ExprEvalPushStep(state, &scratch);
 }
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 0e1a74976f7..51f498bd79a 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -635,7 +635,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			CheckOpSlotCompatibility(op, innerslot);
 
-			slot_getsomeattrs(innerslot, op->d.fetch.last_var);
+			slot_getsomeattrs(innerslot, op->fetch.last_var);
 
 			EEO_NEXT();
 		}
@@ -644,7 +644,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			CheckOpSlotCompatibility(op, outerslot);
 
-			slot_getsomeattrs(outerslot, op->d.fetch.last_var);
+			slot_getsomeattrs(outerslot, op->fetch.last_var);
 
 			EEO_NEXT();
 		}
@@ -653,7 +653,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			CheckOpSlotCompatibility(op, scanslot);
 
-			slot_getsomeattrs(scanslot, op->d.fetch.last_var);
+			slot_getsomeattrs(scanslot, op->fetch.last_var);
 
 			EEO_NEXT();
 		}
@@ -662,7 +662,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			CheckOpSlotCompatibility(op, oldslot);
 
-			slot_getsomeattrs(oldslot, op->d.fetch.last_var);
+			slot_getsomeattrs(oldslot, op->fetch.last_var);
 
 			EEO_NEXT();
 		}
@@ -671,14 +671,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			CheckOpSlotCompatibility(op, newslot);
 
-			slot_getsomeattrs(newslot, op->d.fetch.last_var);
+			slot_getsomeattrs(newslot, op->fetch.last_var);
 
 			EEO_NEXT();
 		}
 
 		EEO_CASE(EEOP_INNER_VAR)
 		{
-			int			attnum = op->d.var.attnum;
+			int			attnum = op->var.attnum;
 
 			/*
 			 * Since we already extracted all referenced columns from the
@@ -695,7 +695,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_OUTER_VAR)
 		{
-			int			attnum = op->d.var.attnum;
+			int			attnum = op->var.attnum;
 
 			/* See EEOP_INNER_VAR comments */
 
@@ -708,7 +708,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_SCAN_VAR)
 		{
-			int			attnum = op->d.var.attnum;
+			int			attnum = op->var.attnum;
 
 			/* See EEOP_INNER_VAR comments */
 
@@ -721,7 +721,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_OLD_VAR)
 		{
-			int			attnum = op->d.var.attnum;
+			int			attnum = op->var.attnum;
 
 			/* See EEOP_INNER_VAR comments */
 
@@ -734,7 +734,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_NEW_VAR)
 		{
-			int			attnum = op->d.var.attnum;
+			int			attnum = op->var.attnum;
 
 			/* See EEOP_INNER_VAR comments */
 
@@ -785,8 +785,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_INNER_VAR)
 		{
-			int			resultnum = op->d.assign_var.resultnum;
-			int			attnum = op->d.assign_var.attnum;
+			int			resultnum = op->assign_var.resultnum;
+			int			attnum = op->assign_var.attnum;
 
 			/*
 			 * We do not need CheckVarSlotCompatibility here; that was taken
@@ -802,8 +802,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_OUTER_VAR)
 		{
-			int			resultnum = op->d.assign_var.resultnum;
-			int			attnum = op->d.assign_var.attnum;
+			int			resultnum = op->assign_var.resultnum;
+			int			attnum = op->assign_var.attnum;
 
 			/*
 			 * We do not need CheckVarSlotCompatibility here; that was taken
@@ -819,8 +819,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_SCAN_VAR)
 		{
-			int			resultnum = op->d.assign_var.resultnum;
-			int			attnum = op->d.assign_var.attnum;
+			int			resultnum = op->assign_var.resultnum;
+			int			attnum = op->assign_var.attnum;
 
 			/*
 			 * We do not need CheckVarSlotCompatibility here; that was taken
@@ -836,8 +836,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_OLD_VAR)
 		{
-			int			resultnum = op->d.assign_var.resultnum;
-			int			attnum = op->d.assign_var.attnum;
+			int			resultnum = op->assign_var.resultnum;
+			int			attnum = op->assign_var.attnum;
 
 			/*
 			 * We do not need CheckVarSlotCompatibility here; that was taken
@@ -853,8 +853,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_NEW_VAR)
 		{
-			int			resultnum = op->d.assign_var.resultnum;
-			int			attnum = op->d.assign_var.attnum;
+			int			resultnum = op->assign_var.resultnum;
+			int			attnum = op->assign_var.attnum;
 
 			/*
 			 * We do not need CheckVarSlotCompatibility here; that was taken
@@ -870,7 +870,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_TMP)
 		{
-			int			resultnum = op->d.assign_tmp.resultnum;
+			int			resultnum = op->assign_tmp.resultnum;
 
 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
 			resultslot->tts_values[resultnum] = state->resvalue;
@@ -881,7 +881,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ASSIGN_TMP_MAKE_RO)
 		{
-			int			resultnum = op->d.assign_tmp.resultnum;
+			int			resultnum = op->assign_tmp.resultnum;
 
 			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
 			resultslot->tts_isnull[resultnum] = state->resnull;
@@ -896,8 +896,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_CONST)
 		{
-			*op->resnull = op->d.constval.isnull;
-			*op->resvalue = op->d.constval.value;
+			*op->resnull = op->constval.isnull;
+			*op->resvalue = op->constval.value;
 
 			EEO_NEXT();
 		}
@@ -919,11 +919,11 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		 */
 		EEO_CASE(EEOP_FUNCEXPR)
 		{
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 			Datum		d;
 
 			fcinfo->isnull = false;
-			d = op->d.func.fn_addr(fcinfo);
+			d = op->func.fn_addr(fcinfo);
 			*op->resvalue = d;
 			*op->resnull = fcinfo->isnull;
 
@@ -933,9 +933,9 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* strict function call with more than two arguments */
 		EEO_CASE(EEOP_FUNCEXPR_STRICT)
 		{
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 			NullableDatum *args = fcinfo->args;
-			int			nargs = op->d.func.nargs;
+			int			nargs = op->func.nargs;
 			Datum		d;
 
 			Assert(nargs > 2);
@@ -950,7 +950,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				}
 			}
 			fcinfo->isnull = false;
-			d = op->d.func.fn_addr(fcinfo);
+			d = op->func.fn_addr(fcinfo);
 			*op->resvalue = d;
 			*op->resnull = fcinfo->isnull;
 
@@ -961,10 +961,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* strict function call with one argument */
 		EEO_CASE(EEOP_FUNCEXPR_STRICT_1)
 		{
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 			NullableDatum *args = fcinfo->args;
 
-			Assert(op->d.func.nargs == 1);
+			Assert(op->func.nargs == 1);
 
 			/* strict function, so check for NULL args */
 			if (args[0].isnull)
@@ -974,7 +974,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				Datum		d;
 
 				fcinfo->isnull = false;
-				d = op->d.func.fn_addr(fcinfo);
+				d = op->func.fn_addr(fcinfo);
 				*op->resvalue = d;
 				*op->resnull = fcinfo->isnull;
 			}
@@ -985,10 +985,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* strict function call with two arguments */
 		EEO_CASE(EEOP_FUNCEXPR_STRICT_2)
 		{
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 			NullableDatum *args = fcinfo->args;
 
-			Assert(op->d.func.nargs == 2);
+			Assert(op->func.nargs == 2);
 
 			/* strict function, so check for NULL args */
 			if (args[0].isnull || args[1].isnull)
@@ -998,7 +998,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				Datum		d;
 
 				fcinfo->isnull = false;
-				d = op->d.func.fn_addr(fcinfo);
+				d = op->func.fn_addr(fcinfo);
 				*op->resvalue = d;
 				*op->resnull = fcinfo->isnull;
 			}
@@ -1034,7 +1034,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		 */
 		EEO_CASE(EEOP_BOOL_AND_STEP_FIRST)
 		{
-			*op->d.boolexpr.anynull = false;
+			*op->boolexpr.anynull = false;
 
 			/*
 			 * EEOP_BOOL_AND_STEP_FIRST resets anynull, otherwise it's the
@@ -1048,13 +1048,13 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			if (*op->resnull)
 			{
-				*op->d.boolexpr.anynull = true;
+				*op->boolexpr.anynull = true;
 			}
 			else if (!DatumGetBool(*op->resvalue))
 			{
 				/* result is already set to FALSE, need not change it */
 				/* bail out early */
-				EEO_JUMP(op->d.boolexpr.jumpdone);
+				EEO_JUMP(op->boolexpr.jumpdone);
 			}
 
 			EEO_NEXT();
@@ -1076,7 +1076,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				 * except more expensive.
 				 */
 			}
-			else if (*op->d.boolexpr.anynull)
+			else if (*op->boolexpr.anynull)
 			{
 				*op->resvalue = (Datum) 0;
 				*op->resnull = true;
@@ -1101,7 +1101,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		 */
 		EEO_CASE(EEOP_BOOL_OR_STEP_FIRST)
 		{
-			*op->d.boolexpr.anynull = false;
+			*op->boolexpr.anynull = false;
 
 			/*
 			 * EEOP_BOOL_OR_STEP_FIRST resets anynull, otherwise it's the same
@@ -1115,13 +1115,13 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			if (*op->resnull)
 			{
-				*op->d.boolexpr.anynull = true;
+				*op->boolexpr.anynull = true;
 			}
 			else if (DatumGetBool(*op->resvalue))
 			{
 				/* result is already set to TRUE, need not change it */
 				/* bail out early */
-				EEO_JUMP(op->d.boolexpr.jumpdone);
+				EEO_JUMP(op->boolexpr.jumpdone);
 			}
 
 			EEO_NEXT();
@@ -1143,7 +1143,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				 * more expensive.
 				 */
 			}
-			else if (*op->d.boolexpr.anynull)
+			else if (*op->boolexpr.anynull)
 			{
 				*op->resvalue = (Datum) 0;
 				*op->resnull = true;
@@ -1180,7 +1180,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				/* ... bail out early, returning FALSE */
 				*op->resnull = false;
 				*op->resvalue = BoolGetDatum(false);
-				EEO_JUMP(op->d.qualexpr.jumpdone);
+				EEO_JUMP(op->qualexpr.jumpdone);
 			}
 
 			/*
@@ -1194,14 +1194,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_JUMP)
 		{
 			/* Unconditionally jump to target step */
-			EEO_JUMP(op->d.jump.jumpdone);
+			EEO_JUMP(op->jump.jumpdone);
 		}
 
 		EEO_CASE(EEOP_JUMP_IF_NULL)
 		{
 			/* Transfer control if current result is null */
 			if (*op->resnull)
-				EEO_JUMP(op->d.jump.jumpdone);
+				EEO_JUMP(op->jump.jumpdone);
 
 			EEO_NEXT();
 		}
@@ -1210,7 +1210,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			/* Transfer control if current result is non-null */
 			if (!*op->resnull)
-				EEO_JUMP(op->d.jump.jumpdone);
+				EEO_JUMP(op->jump.jumpdone);
 
 			EEO_NEXT();
 		}
@@ -1219,7 +1219,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			/* Transfer control if current result is null or false */
 			if (*op->resnull || !DatumGetBool(*op->resvalue))
-				EEO_JUMP(op->d.jump.jumpdone);
+				EEO_JUMP(op->jump.jumpdone);
 
 			EEO_NEXT();
 		}
@@ -1326,7 +1326,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_PARAM_CALLBACK)
 		{
 			/* allow an extension module to supply a PARAM_EXTERN value */
-			op->d.cparam.paramfunc(state, op, econtext);
+			op->cparam.paramfunc(state, op, econtext);
 			EEO_NEXT();
 		}
 
@@ -1339,8 +1339,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_CASE_TESTVAL)
 		{
-			*op->resvalue = *op->d.casetest.value;
-			*op->resnull = *op->d.casetest.isnull;
+			*op->resvalue = *op->casetest.value;
+			*op->resnull = *op->casetest.isnull;
 
 			EEO_NEXT();
 		}
@@ -1358,10 +1358,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			/*
 			 * Force a varlena value that might be read multiple times to R/O
 			 */
-			if (!*op->d.make_readonly.isnull)
+			if (!*op->make_readonly.isnull)
 				*op->resvalue =
-					MakeExpandedObjectReadOnlyInternal(*op->d.make_readonly.value);
-			*op->resnull = *op->d.make_readonly.isnull;
+					MakeExpandedObjectReadOnlyInternal(*op->make_readonly.value);
+			*op->resnull = *op->make_readonly.isnull;
 
 			EEO_NEXT();
 		}
@@ -1388,7 +1388,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			{
 				FunctionCallInfo fcinfo_out;
 
-				fcinfo_out = op->d.iocoerce.fcinfo_data_out;
+				fcinfo_out = op->iocoerce.fcinfo_data_out;
 				fcinfo_out->args[0].value = *op->resvalue;
 				fcinfo_out->args[0].isnull = false;
 
@@ -1400,12 +1400,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			}
 
 			/* call input function (similar to InputFunctionCall) */
-			if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
+			if (!op->iocoerce.finfo_in->fn_strict || str != NULL)
 			{
 				FunctionCallInfo fcinfo_in;
 				Datum		d;
 
-				fcinfo_in = op->d.iocoerce.fcinfo_data_in;
+				fcinfo_in = op->iocoerce.fcinfo_data_in;
 				fcinfo_in->args[0].value = PointerGetDatum(str);
 				fcinfo_in->args[0].isnull = *op->resnull;
 				/* second and third arguments are already set up */
@@ -1447,7 +1447,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			 * that function is strict.  Because the handling of nulls is
 			 * different, we can't just reuse EEOP_FUNCEXPR.
 			 */
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 
 			/* check function arguments for NULLness */
 			if (fcinfo->args[0].isnull && fcinfo->args[1].isnull)
@@ -1468,7 +1468,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				Datum		eqresult;
 
 				fcinfo->isnull = false;
-				eqresult = op->d.func.fn_addr(fcinfo);
+				eqresult = op->func.fn_addr(fcinfo);
 				/* Must invert result of "="; safe to do even if null */
 				*op->resvalue = BoolGetDatum(!DatumGetBool(eqresult));
 				*op->resnull = fcinfo->isnull;
@@ -1480,7 +1480,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* see EEOP_DISTINCT for comments, this is just inverted */
 		EEO_CASE(EEOP_NOT_DISTINCT)
 		{
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 
 			if (fcinfo->args[0].isnull && fcinfo->args[1].isnull)
 			{
@@ -1497,7 +1497,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				Datum		eqresult;
 
 				fcinfo->isnull = false;
-				eqresult = op->d.func.fn_addr(fcinfo);
+				eqresult = op->func.fn_addr(fcinfo);
 				*op->resvalue = eqresult;
 				*op->resnull = fcinfo->isnull;
 			}
@@ -1510,7 +1510,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			/*
 			 * The arguments are already evaluated into fcinfo->args.
 			 */
-			FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+			FunctionCallInfo fcinfo = op->func.fcinfo_data;
 			Datum		save_arg0 = fcinfo->args[0].value;
 
 			/* if either argument is NULL they can't be equal */
@@ -1525,12 +1525,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				 * if we end by returning the first argument, that will be the
 				 * original read-write pointer if it was read-write.
 				 */
-				if (op->d.func.make_ro)
+				if (op->func.make_ro)
 					fcinfo->args[0].value =
 						MakeExpandedObjectReadOnlyInternal(save_arg0);
 
 				fcinfo->isnull = false;
-				result = op->d.func.fn_addr(fcinfo);
+				result = op->func.fn_addr(fcinfo);
 
 				/* if the arguments are equal return null */
 				if (!fcinfo->isnull && DatumGetBool(result))
@@ -1585,12 +1585,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			 * The next op actually evaluates the expression.  If the OLD/NEW
 			 * row doesn't exist, skip that and return NULL.
 			 */
-			if (state->flags & op->d.returningexpr.nullflag)
+			if (state->flags & op->returningexpr.nullflag)
 			{
 				*op->resvalue = (Datum) 0;
 				*op->resnull = true;
 
-				EEO_JUMP(op->d.returningexpr.jumpdone);
+				EEO_JUMP(op->returningexpr.jumpdone);
 			}
 
 			EEO_NEXT();
@@ -1622,34 +1622,34 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_ROWCOMPARE_STEP)
 		{
-			FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data;
+			FunctionCallInfo fcinfo = op->rowcompare_step.fcinfo_data;
 			Datum		d;
 
 			/* force NULL result if strict fn and NULL input */
-			if (op->d.rowcompare_step.finfo->fn_strict &&
+			if (op->rowcompare_step.finfo->fn_strict &&
 				(fcinfo->args[0].isnull || fcinfo->args[1].isnull))
 			{
 				*op->resnull = true;
-				EEO_JUMP(op->d.rowcompare_step.jumpnull);
+				EEO_JUMP(op->rowcompare_step.jumpnull);
 			}
 
 			/* Apply comparison function */
 			fcinfo->isnull = false;
-			d = op->d.rowcompare_step.fn_addr(fcinfo);
+			d = op->rowcompare_step.fn_addr(fcinfo);
 			*op->resvalue = d;
 
 			/* force NULL result if NULL function result */
 			if (fcinfo->isnull)
 			{
 				*op->resnull = true;
-				EEO_JUMP(op->d.rowcompare_step.jumpnull);
+				EEO_JUMP(op->rowcompare_step.jumpnull);
 			}
 			*op->resnull = false;
 
 			/* If unequal, no need to compare remaining columns */
 			if (DatumGetInt32(*op->resvalue) != 0)
 			{
-				EEO_JUMP(op->d.rowcompare_step.jumpdone);
+				EEO_JUMP(op->rowcompare_step.jumpdone);
 			}
 
 			EEO_NEXT();
@@ -1658,7 +1658,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_ROWCOMPARE_FINAL)
 		{
 			int32		cmpresult = DatumGetInt32(*op->resvalue);
-			CompareType cmptype = op->d.rowcompare_final.cmptype;
+			CompareType cmptype = op->rowcompare_final.cmptype;
 
 			*op->resnull = false;
 			switch (cmptype)
@@ -1719,14 +1719,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_SBSREF_SUBSCRIPTS)
 		{
 			/* Precheck SubscriptingRef subscript(s) */
-			if (op->d.sbsref_subscript.subscriptfunc(state, op, econtext))
+			if (op->sbsref_subscript.subscriptfunc(state, op, econtext))
 			{
 				EEO_NEXT();
 			}
 			else
 			{
 				/* Subscript is null, short-circuit SubscriptingRef to NULL */
-				EEO_JUMP(op->d.sbsref_subscript.jumpdone);
+				EEO_JUMP(op->sbsref_subscript.jumpdone);
 			}
 		}
 
@@ -1735,7 +1735,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			EEO_CASE(EEOP_SBSREF_FETCH)
 		{
 			/* Perform a SubscriptingRef fetch or assignment */
-			op->d.sbsref.subscriptfunc(state, op, econtext);
+			op->sbsref.subscriptfunc(state, op, econtext);
 
 			EEO_NEXT();
 		}
@@ -1766,8 +1766,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_DOMAIN_TESTVAL)
 		{
-			*op->resvalue = *op->d.casetest.value;
-			*op->resnull = *op->d.casetest.isnull;
+			*op->resvalue = *op->casetest.value;
+			*op->resnull = *op->casetest.isnull;
 
 			EEO_NEXT();
 		}
@@ -1798,7 +1798,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_HASHDATUM_SET_INITVAL)
 		{
-			*op->resvalue = op->d.hashdatum_initvalue.init_value;
+			*op->resvalue = op->hashdatum_initvalue.init_value;
 			*op->resnull = false;
 
 			EEO_NEXT();
@@ -1806,14 +1806,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_HASHDATUM_FIRST)
 		{
-			FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data;
+			FunctionCallInfo fcinfo = op->hashdatum.fcinfo_data;
 
 			/*
 			 * Save the Datum on non-null inputs, otherwise store 0 so that
 			 * subsequent NEXT32 operations combine with an initialized value.
 			 */
 			if (!fcinfo->args[0].isnull)
-				*op->resvalue = op->d.hashdatum.fn_addr(fcinfo);
+				*op->resvalue = op->hashdatum.fn_addr(fcinfo);
 			else
 				*op->resvalue = (Datum) 0;
 
@@ -1824,7 +1824,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_HASHDATUM_FIRST_STRICT)
 		{
-			FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data;
+			FunctionCallInfo fcinfo = op->hashdatum.fcinfo_data;
 
 			if (fcinfo->args[0].isnull)
 			{
@@ -1835,11 +1835,11 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				 */
 				*op->resnull = true;
 				*op->resvalue = (Datum) 0;
-				EEO_JUMP(op->d.hashdatum.jumpdone);
+				EEO_JUMP(op->hashdatum.jumpdone);
 			}
 
 			/* execute the hash function and save the resulting value */
-			*op->resvalue = op->d.hashdatum.fn_addr(fcinfo);
+			*op->resvalue = op->hashdatum.fn_addr(fcinfo);
 			*op->resnull = false;
 
 			EEO_NEXT();
@@ -1847,10 +1847,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_HASHDATUM_NEXT32)
 		{
-			FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data;
+			FunctionCallInfo fcinfo = op->hashdatum.fcinfo_data;
 			uint32		existinghash;
 
-			existinghash = DatumGetUInt32(op->d.hashdatum.iresult->value);
+			existinghash = DatumGetUInt32(op->hashdatum.iresult->value);
 			/* combine successive hash values by rotating */
 			existinghash = pg_rotate_left32(existinghash, 1);
 
@@ -1860,7 +1860,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				uint32		hashvalue;
 
 				/* execute hash func and combine with previous hash value */
-				hashvalue = DatumGetUInt32(op->d.hashdatum.fn_addr(fcinfo));
+				hashvalue = DatumGetUInt32(op->hashdatum.fn_addr(fcinfo));
 				existinghash = existinghash ^ hashvalue;
 			}
 
@@ -1872,7 +1872,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 
 		EEO_CASE(EEOP_HASHDATUM_NEXT32_STRICT)
 		{
-			FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data;
+			FunctionCallInfo fcinfo = op->hashdatum.fcinfo_data;
 
 			if (fcinfo->args[0].isnull)
 			{
@@ -1883,19 +1883,19 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 				 */
 				*op->resnull = true;
 				*op->resvalue = (Datum) 0;
-				EEO_JUMP(op->d.hashdatum.jumpdone);
+				EEO_JUMP(op->hashdatum.jumpdone);
 			}
 			else
 			{
 				uint32		existinghash;
 				uint32		hashvalue;
 
-				existinghash = DatumGetUInt32(op->d.hashdatum.iresult->value);
+				existinghash = DatumGetUInt32(op->hashdatum.iresult->value);
 				/* combine successive hash values by rotating */
 				existinghash = pg_rotate_left32(existinghash, 1);
 
 				/* execute hash func and combine with previous hash value */
-				hashvalue = DatumGetUInt32(op->d.hashdatum.fn_addr(fcinfo));
+				hashvalue = DatumGetUInt32(op->hashdatum.fn_addr(fcinfo));
 				*op->resvalue = UInt32GetDatum(existinghash ^ hashvalue);
 				*op->resnull = false;
 			}
@@ -1954,7 +1954,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			 * Returns a Datum whose value is the precomputed aggregate value
 			 * found in the given expression context.
 			 */
-			int			aggno = op->d.aggref.aggno;
+			int			aggno = op->aggref.aggno;
 
 			Assert(econtext->ecxt_aggvalues != NULL);
 
@@ -1977,7 +1977,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			/*
 			 * Like Aggref, just return a precomputed value from the econtext.
 			 */
-			WindowFuncExprState *wfunc = op->d.window_func.wfstate;
+			WindowFuncExprState *wfunc = op->window_func.wfstate;
 
 			Assert(econtext->ecxt_aggvalues != NULL);
 
@@ -2007,8 +2007,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE)
 		{
 			/* Don't call a strict deserialization function with NULL input */
-			if (op->d.agg_deserialize.fcinfo_data->args[0].isnull)
-				EEO_JUMP(op->d.agg_deserialize.jumpnull);
+			if (op->agg_deserialize.fcinfo_data->args[0].isnull)
+				EEO_JUMP(op->agg_deserialize.jumpnull);
 
 			/* fallthrough */
 		}
@@ -2016,7 +2016,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* evaluate aggregate deserialization function (non-strict portion) */
 		EEO_CASE(EEOP_AGG_DESERIALIZE)
 		{
-			FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data;
+			FunctionCallInfo fcinfo = op->agg_deserialize.fcinfo_data;
 			AggState   *aggstate = castNode(AggState, state->parent);
 			MemoryContext oldContext;
 
@@ -2041,15 +2041,15 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* when checking more than one argument */
 		EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS)
 		{
-			NullableDatum *args = op->d.agg_strict_input_check.args;
-			int			nargs = op->d.agg_strict_input_check.nargs;
+			NullableDatum *args = op->agg_strict_input_check.args;
+			int			nargs = op->agg_strict_input_check.nargs;
 
 			Assert(nargs > 1);
 
 			for (int argno = 0; argno < nargs; argno++)
 			{
 				if (args[argno].isnull)
-					EEO_JUMP(op->d.agg_strict_input_check.jumpnull);
+					EEO_JUMP(op->agg_strict_input_check.jumpnull);
 			}
 			EEO_NEXT();
 		}
@@ -2057,25 +2057,25 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		/* special case for just one argument */
 		EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1)
 		{
-			NullableDatum *args = op->d.agg_strict_input_check.args;
-			PG_USED_FOR_ASSERTS_ONLY int nargs = op->d.agg_strict_input_check.nargs;
+			NullableDatum *args = op->agg_strict_input_check.args;
+			PG_USED_FOR_ASSERTS_ONLY int nargs = op->agg_strict_input_check.nargs;
 
 			Assert(nargs == 1);
 
 			if (args[0].isnull)
-				EEO_JUMP(op->d.agg_strict_input_check.jumpnull);
+				EEO_JUMP(op->agg_strict_input_check.jumpnull);
 			EEO_NEXT();
 		}
 
 		EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
 		{
-			bool	   *nulls = op->d.agg_strict_input_check.nulls;
-			int			nargs = op->d.agg_strict_input_check.nargs;
+			bool	   *nulls = op->agg_strict_input_check.nulls;
+			int			nargs = op->agg_strict_input_check.nargs;
 
 			for (int argno = 0; argno < nargs; argno++)
 			{
 				if (nulls[argno])
-					EEO_JUMP(op->d.agg_strict_input_check.jumpnull);
+					EEO_JUMP(op->agg_strict_input_check.jumpnull);
 			}
 			EEO_NEXT();
 		}
@@ -2088,10 +2088,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
 			AggStatePerGroup pergroup_allaggs =
-				aggstate->all_pergroups[op->d.agg_plain_pergroup_nullcheck.setoff];
+				aggstate->all_pergroups[op->agg_plain_pergroup_nullcheck.setoff];
 
 			if (pergroup_allaggs == NULL)
-				EEO_JUMP(op->d.agg_plain_pergroup_nullcheck.jumpnull);
+				EEO_JUMP(op->agg_plain_pergroup_nullcheck.jumpnull);
 
 			EEO_NEXT();
 		}
@@ -2111,9 +2111,9 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
+			AggStatePerTrans pertrans = op->agg_trans.pertrans;
 			AggStatePerGroup pergroup =
-				&aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno];
+				&aggstate->all_pergroups[op->agg_trans.setoff][op->agg_trans.transno];
 
 			Assert(pertrans->transtypeByVal);
 
@@ -2121,15 +2121,15 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 			{
 				/* If transValue has not yet been initialized, do so now. */
 				ExecAggInitGroup(aggstate, pertrans, pergroup,
-								 op->d.agg_trans.aggcontext);
+								 op->agg_trans.aggcontext);
 				/* copied trans value from input, done this round */
 			}
 			else if (likely(!pergroup->transValueIsNull))
 			{
 				/* invoke transition function, unless prevented by strictness */
 				ExecAggPlainTransByVal(aggstate, pertrans, pergroup,
-									   op->d.agg_trans.aggcontext,
-									   op->d.agg_trans.setno);
+									   op->agg_trans.aggcontext,
+									   op->agg_trans.setno);
 			}
 
 			EEO_NEXT();
@@ -2139,16 +2139,16 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
+			AggStatePerTrans pertrans = op->agg_trans.pertrans;
 			AggStatePerGroup pergroup =
-				&aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno];
+				&aggstate->all_pergroups[op->agg_trans.setoff][op->agg_trans.transno];
 
 			Assert(pertrans->transtypeByVal);
 
 			if (likely(!pergroup->transValueIsNull))
 				ExecAggPlainTransByVal(aggstate, pertrans, pergroup,
-									   op->d.agg_trans.aggcontext,
-									   op->d.agg_trans.setno);
+									   op->agg_trans.aggcontext,
+									   op->agg_trans.setno);
 
 			EEO_NEXT();
 		}
@@ -2157,15 +2157,15 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYVAL)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
+			AggStatePerTrans pertrans = op->agg_trans.pertrans;
 			AggStatePerGroup pergroup =
-				&aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno];
+				&aggstate->all_pergroups[op->agg_trans.setoff][op->agg_trans.transno];
 
 			Assert(pertrans->transtypeByVal);
 
 			ExecAggPlainTransByVal(aggstate, pertrans, pergroup,
-								   op->d.agg_trans.aggcontext,
-								   op->d.agg_trans.setno);
+								   op->agg_trans.aggcontext,
+								   op->agg_trans.setno);
 
 			EEO_NEXT();
 		}
@@ -2174,19 +2174,19 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
+			AggStatePerTrans pertrans = op->agg_trans.pertrans;
 			AggStatePerGroup pergroup =
-				&aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno];
+				&aggstate->all_pergroups[op->agg_trans.setoff][op->agg_trans.transno];
 
 			Assert(!pertrans->transtypeByVal);
 
 			if (pergroup->noTransValue)
 				ExecAggInitGroup(aggstate, pertrans, pergroup,
-								 op->d.agg_trans.aggcontext);
+								 op->agg_trans.aggcontext);
 			else if (likely(!pergroup->transValueIsNull))
 				ExecAggPlainTransByRef(aggstate, pertrans, pergroup,
-									   op->d.agg_trans.aggcontext,
-									   op->d.agg_trans.setno);
+									   op->agg_trans.aggcontext,
+									   op->agg_trans.setno);
 
 			EEO_NEXT();
 		}
@@ -2195,16 +2195,16 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_PLAIN_TRANS_STRICT_BYREF)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
+			AggStatePerTrans pertrans = op->agg_trans.pertrans;
 			AggStatePerGroup pergroup =
-				&aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno];
+				&aggstate->all_pergroups[op->agg_trans.setoff][op->agg_trans.transno];
 
 			Assert(!pertrans->transtypeByVal);
 
 			if (likely(!pergroup->transValueIsNull))
 				ExecAggPlainTransByRef(aggstate, pertrans, pergroup,
-									   op->d.agg_trans.aggcontext,
-									   op->d.agg_trans.setno);
+									   op->agg_trans.aggcontext,
+									   op->agg_trans.setno);
 			EEO_NEXT();
 		}
 
@@ -2212,39 +2212,39 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 		EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYREF)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
+			AggStatePerTrans pertrans = op->agg_trans.pertrans;
 			AggStatePerGroup pergroup =
-				&aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno];
+				&aggstate->all_pergroups[op->agg_trans.setoff][op->agg_trans.transno];
 
 			Assert(!pertrans->transtypeByVal);
 
 			ExecAggPlainTransByRef(aggstate, pertrans, pergroup,
-								   op->d.agg_trans.aggcontext,
-								   op->d.agg_trans.setno);
+								   op->agg_trans.aggcontext,
+								   op->agg_trans.setno);
 
 			EEO_NEXT();
 		}
 
 		EEO_CASE(EEOP_AGG_PRESORTED_DISTINCT_SINGLE)
 		{
-			AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
+			AggStatePerTrans pertrans = op->agg_presorted_distinctcheck.pertrans;
 			AggState   *aggstate = castNode(AggState, state->parent);
 
 			if (ExecEvalPreOrderedDistinctSingle(aggstate, pertrans))
 				EEO_NEXT();
 			else
-				EEO_JUMP(op->d.agg_presorted_distinctcheck.jumpdistinct);
+				EEO_JUMP(op->agg_presorted_distinctcheck.jumpdistinct);
 		}
 
 		EEO_CASE(EEOP_AGG_PRESORTED_DISTINCT_MULTI)
 		{
 			AggState   *aggstate = castNode(AggState, state->parent);
-			AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
+			AggStatePerTrans pertrans = op->agg_presorted_distinctcheck.pertrans;
 
 			if (ExecEvalPreOrderedDistinctMulti(aggstate, pertrans))
 				EEO_NEXT();
 			else
-				EEO_JUMP(op->d.agg_presorted_distinctcheck.jumpdistinct);
+				EEO_JUMP(op->agg_presorted_distinctcheck.jumpdistinct);
 		}
 
 		/* process single-column ordered aggregate datum */
@@ -2326,41 +2326,41 @@ CheckExprStillValid(ExprState *state, ExprContext *econtext)
 		{
 			case EEOP_INNER_VAR:
 				{
-					int			attnum = op->d.var.attnum;
+					int			attnum = op->var.attnum;
 
-					CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
+					CheckVarSlotCompatibility(innerslot, attnum + 1, op->var.vartype);
 					break;
 				}
 
 			case EEOP_OUTER_VAR:
 				{
-					int			attnum = op->d.var.attnum;
+					int			attnum = op->var.attnum;
 
-					CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
+					CheckVarSlotCompatibility(outerslot, attnum + 1, op->var.vartype);
 					break;
 				}
 
 			case EEOP_SCAN_VAR:
 				{
-					int			attnum = op->d.var.attnum;
+					int			attnum = op->var.attnum;
 
-					CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
+					CheckVarSlotCompatibility(scanslot, attnum + 1, op->var.vartype);
 					break;
 				}
 
 			case EEOP_OLD_VAR:
 				{
-					int			attnum = op->d.var.attnum;
+					int			attnum = op->var.attnum;
 
-					CheckVarSlotCompatibility(oldslot, attnum + 1, op->d.var.vartype);
+					CheckVarSlotCompatibility(oldslot, attnum + 1, op->var.vartype);
 					break;
 				}
 
 			case EEOP_NEW_VAR:
 				{
-					int			attnum = op->d.var.attnum;
+					int			attnum = op->var.attnum;
 
-					CheckVarSlotCompatibility(newslot, attnum + 1, op->d.var.vartype);
+					CheckVarSlotCompatibility(newslot, attnum + 1, op->var.vartype);
 					break;
 				}
 			default:
@@ -2434,7 +2434,7 @@ CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot)
 {
 #ifdef USE_ASSERT_CHECKING
 	/* there's nothing to check */
-	if (!op->d.fetch.fixed)
+	if (!op->fetch.fixed)
 		return;
 
 	/*
@@ -2442,10 +2442,10 @@ CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot)
 	 * buffer and heap tuples to be used interchangeably.
 	 */
 	if (slot->tts_ops == &TTSOpsBufferHeapTuple &&
-		op->d.fetch.kind == &TTSOpsHeapTuple)
+		op->fetch.kind == &TTSOpsHeapTuple)
 		return;
 	if (slot->tts_ops == &TTSOpsHeapTuple &&
-		op->d.fetch.kind == &TTSOpsBufferHeapTuple)
+		op->fetch.kind == &TTSOpsBufferHeapTuple)
 		return;
 
 	/*
@@ -2455,7 +2455,7 @@ CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot)
 	if (slot->tts_ops == &TTSOpsVirtual)
 		return;
 
-	Assert(op->d.fetch.kind == slot->tts_ops);
+	Assert(op->fetch.kind == slot->tts_ops);
 #endif
 }
 
@@ -2546,7 +2546,7 @@ static pg_attribute_always_inline Datum
 ExecJustVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
 {
 	ExprEvalStep *op = &state->steps[1];
-	int			attnum = op->d.var.attnum + 1;
+	int			attnum = op->var.attnum + 1;
 
 	CheckOpSlotCompatibility(&state->steps[0], slot);
 
@@ -2584,8 +2584,8 @@ static pg_attribute_always_inline Datum
 ExecJustAssignVarImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull)
 {
 	ExprEvalStep *op = &state->steps[1];
-	int			attnum = op->d.assign_var.attnum + 1;
-	int			resultnum = op->d.assign_var.resultnum;
+	int			attnum = op->assign_var.attnum + 1;
+	int			resultnum = op->assign_var.resultnum;
 	TupleTableSlot *outslot = state->resultslot;
 
 	CheckOpSlotCompatibility(&state->steps[0], inslot);
@@ -2640,13 +2640,13 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
 	 * XXX with some redesign of the CaseTestExpr mechanism, maybe we could
 	 * get rid of this data shuffling?
 	 */
-	*op->resvalue = *op->d.casetest.value;
-	*op->resnull = *op->d.casetest.isnull;
+	*op->resvalue = *op->casetest.value;
+	*op->resnull = *op->casetest.isnull;
 
 	op++;
 
-	nargs = op->d.func.nargs;
-	fcinfo = op->d.func.fcinfo_data;
+	nargs = op->func.nargs;
+	fcinfo = op->func.fcinfo_data;
 	args = fcinfo->args;
 
 	/* strict function, so check for NULL args */
@@ -2659,7 +2659,7 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
 		}
 	}
 	fcinfo->isnull = false;
-	d = op->d.func.fn_addr(fcinfo);
+	d = op->func.fn_addr(fcinfo);
 	*isnull = fcinfo->isnull;
 	return d;
 }
@@ -2670,8 +2670,8 @@ ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull)
 {
 	ExprEvalStep *op = &state->steps[0];
 
-	*isnull = op->d.constval.isnull;
-	return op->d.constval.value;
+	*isnull = op->constval.isnull;
+	return op->constval.value;
 }
 
 /* implementation of ExecJust(Inner|Outer|Scan)VarVirt */
@@ -2679,7 +2679,7 @@ static pg_attribute_always_inline Datum
 ExecJustVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
 {
 	ExprEvalStep *op = &state->steps[0];
-	int			attnum = op->d.var.attnum;
+	int			attnum = op->var.attnum;
 
 	/*
 	 * As it is guaranteed that a virtual slot is used, there never is a need
@@ -2722,8 +2722,8 @@ static pg_attribute_always_inline Datum
 ExecJustAssignVarVirtImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull)
 {
 	ExprEvalStep *op = &state->steps[0];
-	int			attnum = op->d.assign_var.attnum;
-	int			resultnum = op->d.assign_var.resultnum;
+	int			attnum = op->assign_var.attnum;
+	int			resultnum = op->assign_var.resultnum;
 	TupleTableSlot *outslot = state->resultslot;
 
 	/* see ExecJustVarVirtImpl for comments */
@@ -2771,24 +2771,24 @@ ExecJustHashInnerVarWithIV(ExprState *state, ExprContext *econtext,
 	ExprEvalStep *setivop = &state->steps[1];
 	ExprEvalStep *innervar = &state->steps[2];
 	ExprEvalStep *hashop = &state->steps[3];
-	FunctionCallInfo fcinfo = hashop->d.hashdatum.fcinfo_data;
-	int			attnum = innervar->d.var.attnum;
+	FunctionCallInfo fcinfo = hashop->hashdatum.fcinfo_data;
+	int			attnum = innervar->var.attnum;
 	uint32		hashkey;
 
 	CheckOpSlotCompatibility(fetchop, econtext->ecxt_innertuple);
-	slot_getsomeattrs(econtext->ecxt_innertuple, fetchop->d.fetch.last_var);
+	slot_getsomeattrs(econtext->ecxt_innertuple, fetchop->fetch.last_var);
 
 	fcinfo->args[0].value = econtext->ecxt_innertuple->tts_values[attnum];
 	fcinfo->args[0].isnull = econtext->ecxt_innertuple->tts_isnull[attnum];
 
-	hashkey = DatumGetUInt32(setivop->d.hashdatum_initvalue.init_value);
+	hashkey = DatumGetUInt32(setivop->hashdatum_initvalue.init_value);
 	hashkey = pg_rotate_left32(hashkey, 1);
 
 	if (!fcinfo->args[0].isnull)
 	{
 		uint32		hashvalue;
 
-		hashvalue = DatumGetUInt32(hashop->d.hashdatum.fn_addr(fcinfo));
+		hashvalue = DatumGetUInt32(hashop->hashdatum.fn_addr(fcinfo));
 		hashkey = hashkey ^ hashvalue;
 	}
 
@@ -2803,11 +2803,11 @@ ExecJustHashVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
 	ExprEvalStep *fetchop = &state->steps[0];
 	ExprEvalStep *var = &state->steps[1];
 	ExprEvalStep *hashop = &state->steps[2];
-	FunctionCallInfo fcinfo = hashop->d.hashdatum.fcinfo_data;
-	int			attnum = var->d.var.attnum;
+	FunctionCallInfo fcinfo = hashop->hashdatum.fcinfo_data;
+	int			attnum = var->var.attnum;
 
 	CheckOpSlotCompatibility(fetchop, slot);
-	slot_getsomeattrs(slot, fetchop->d.fetch.last_var);
+	slot_getsomeattrs(slot, fetchop->fetch.last_var);
 
 	fcinfo->args[0].value = slot->tts_values[attnum];
 	fcinfo->args[0].isnull = slot->tts_isnull[attnum];
@@ -2815,7 +2815,7 @@ ExecJustHashVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
 	*isnull = false;
 
 	if (!fcinfo->args[0].isnull)
-		return hashop->d.hashdatum.fn_addr(fcinfo);
+		return hashop->hashdatum.fn_addr(fcinfo);
 	else
 		return (Datum) 0;
 }
@@ -2840,8 +2840,8 @@ ExecJustHashVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
 {
 	ExprEvalStep *var = &state->steps[0];
 	ExprEvalStep *hashop = &state->steps[1];
-	FunctionCallInfo fcinfo = hashop->d.hashdatum.fcinfo_data;
-	int			attnum = var->d.var.attnum;
+	FunctionCallInfo fcinfo = hashop->hashdatum.fcinfo_data;
+	int			attnum = var->var.attnum;
 
 	fcinfo->args[0].value = slot->tts_values[attnum];
 	fcinfo->args[0].isnull = slot->tts_isnull[attnum];
@@ -2849,7 +2849,7 @@ ExecJustHashVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
 	*isnull = false;
 
 	if (!fcinfo->args[0].isnull)
-		return hashop->d.hashdatum.fn_addr(fcinfo);
+		return hashop->hashdatum.fn_addr(fcinfo);
 	else
 		return (Datum) 0;
 }
@@ -2880,11 +2880,11 @@ ExecJustHashOuterVarStrict(ExprState *state, ExprContext *econtext,
 	ExprEvalStep *fetchop = &state->steps[0];
 	ExprEvalStep *var = &state->steps[1];
 	ExprEvalStep *hashop = &state->steps[2];
-	FunctionCallInfo fcinfo = hashop->d.hashdatum.fcinfo_data;
-	int			attnum = var->d.var.attnum;
+	FunctionCallInfo fcinfo = hashop->hashdatum.fcinfo_data;
+	int			attnum = var->var.attnum;
 
 	CheckOpSlotCompatibility(fetchop, econtext->ecxt_outertuple);
-	slot_getsomeattrs(econtext->ecxt_outertuple, fetchop->d.fetch.last_var);
+	slot_getsomeattrs(econtext->ecxt_outertuple, fetchop->fetch.last_var);
 
 	fcinfo->args[0].value = econtext->ecxt_outertuple->tts_values[attnum];
 	fcinfo->args[0].isnull = econtext->ecxt_outertuple->tts_isnull[attnum];
@@ -2892,7 +2892,7 @@ ExecJustHashOuterVarStrict(ExprState *state, ExprContext *econtext,
 	if (!fcinfo->args[0].isnull)
 	{
 		*isnull = false;
-		return hashop->d.hashdatum.fn_addr(fcinfo);
+		return hashop->hashdatum.fn_addr(fcinfo);
 	}
 	else
 	{
@@ -2990,14 +2990,14 @@ void
 ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op,
 					   ExprContext *econtext)
 {
-	FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+	FunctionCallInfo fcinfo = op->func.fcinfo_data;
 	PgStat_FunctionCallUsage fcusage;
 	Datum		d;
 
 	pgstat_init_function_usage(fcinfo, &fcusage);
 
 	fcinfo->isnull = false;
-	d = op->d.func.fn_addr(fcinfo);
+	d = op->func.fn_addr(fcinfo);
 	*op->resvalue = d;
 	*op->resnull = fcinfo->isnull;
 
@@ -3012,10 +3012,10 @@ ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
 							 ExprContext *econtext)
 {
 
-	FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+	FunctionCallInfo fcinfo = op->func.fcinfo_data;
 	PgStat_FunctionCallUsage fcusage;
 	NullableDatum *args = fcinfo->args;
-	int			nargs = op->d.func.nargs;
+	int			nargs = op->func.nargs;
 	Datum		d;
 
 	/* strict function, so check for NULL args */
@@ -3031,7 +3031,7 @@ ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
 	pgstat_init_function_usage(fcinfo, &fcusage);
 
 	fcinfo->isnull = false;
-	d = op->d.func.fn_addr(fcinfo);
+	d = op->func.fn_addr(fcinfo);
 	*op->resvalue = d;
 	*op->resnull = fcinfo->isnull;
 
@@ -3049,7 +3049,7 @@ ExecEvalParamExec(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
 	ParamExecData *prm;
 
-	prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
+	prm = &(econtext->ecxt_param_exec_vals[op->param.paramid]);
 	if (unlikely(prm->execPlan != NULL))
 	{
 		/* Parameter not evaluated yet, so go do it */
@@ -3070,7 +3070,7 @@ void
 ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
 	ParamListInfo paramInfo = econtext->ecxt_param_list_info;
-	int			paramId = op->d.param.paramid;
+	int			paramId = op->param.paramid;
 
 	if (likely(paramInfo &&
 			   paramId > 0 && paramId <= paramInfo->numParams))
@@ -3087,13 +3087,13 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 		if (likely(OidIsValid(prm->ptype)))
 		{
 			/* safety check in case hook did something unexpected */
-			if (unlikely(prm->ptype != op->d.param.paramtype))
+			if (unlikely(prm->ptype != op->param.paramtype))
 				ereport(ERROR,
 						(errcode(ERRCODE_DATATYPE_MISMATCH),
 						 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
 								paramId,
 								format_type_be(prm->ptype),
-								format_type_be(op->d.param.paramtype))));
+								format_type_be(op->param.paramtype))));
 			*op->resvalue = prm->value;
 			*op->resnull = prm->isnull;
 			return;
@@ -3114,7 +3114,7 @@ ExecEvalParamSet(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
 	ParamExecData *prm;
 
-	prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
+	prm = &(econtext->ecxt_param_exec_vals[op->param.paramid]);
 
 	/* Shouldn't have a pending evaluation anymore */
 	Assert(prm->execPlan == NULL);
@@ -3146,7 +3146,7 @@ ExecEvalCoerceViaIOSafe(ExprState *state, ExprEvalStep *op)
 	{
 		FunctionCallInfo fcinfo_out;
 
-		fcinfo_out = op->d.iocoerce.fcinfo_data_out;
+		fcinfo_out = op->iocoerce.fcinfo_data_out;
 		fcinfo_out->args[0].value = *op->resvalue;
 		fcinfo_out->args[0].isnull = false;
 
@@ -3158,11 +3158,11 @@ ExecEvalCoerceViaIOSafe(ExprState *state, ExprEvalStep *op)
 	}
 
 	/* call input function (similar to InputFunctionCallSafe) */
-	if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
+	if (!op->iocoerce.finfo_in->fn_strict || str != NULL)
 	{
 		FunctionCallInfo fcinfo_in;
 
-		fcinfo_in = op->d.iocoerce.fcinfo_data_in;
+		fcinfo_in = op->iocoerce.fcinfo_data_in;
 		fcinfo_in->args[0].value = PointerGetDatum(str);
 		fcinfo_in->args[0].isnull = *op->resnull;
 		/* second and third arguments are already set up */
@@ -3195,7 +3195,7 @@ void
 ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
 {
 	LOCAL_FCINFO(fcinfo, 0);
-	SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
+	SQLValueFunction *svf = op->sqlvaluefunction.svf;
 
 	*op->resnull = false;
 
@@ -3272,9 +3272,9 @@ ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op)
 void
 ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op)
 {
-	int64		newval = nextval_internal(op->d.nextvalueexpr.seqid, false);
+	int64		newval = nextval_internal(op->nextvalueexpr.seqid, false);
 
-	switch (op->d.nextvalueexpr.seqtypid)
+	switch (op->nextvalueexpr.seqtypid)
 	{
 		case INT2OID:
 			*op->resvalue = Int16GetDatum((int16) newval);
@@ -3287,7 +3287,7 @@ ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op)
 			break;
 		default:
 			elog(ERROR, "unsupported sequence type %u",
-				 op->d.nextvalueexpr.seqtypid);
+				 op->nextvalueexpr.seqtypid);
 	}
 	*op->resnull = false;
 }
@@ -3355,7 +3355,7 @@ ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op,
 
 	/* Lookup tupdesc if first time through or if type changes */
 	tupDesc = get_cached_rowtype(tupType, tupTypmod,
-								 &op->d.nulltest_row.rowcache, NULL);
+								 &op->nulltest_row.rowcache, NULL);
 
 	/*
 	 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
@@ -3395,14 +3395,14 @@ ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op,
  * Evaluate an ARRAY[] expression.
  *
  * The individual array elements (or subarrays) have already been evaluated
- * into op->d.arrayexpr.elemvalues[]/elemnulls[].
+ * into op->arrayexpr.elemvalues[]/elemnulls[].
  */
 void
 ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
 {
 	ArrayType  *result;
-	Oid			element_type = op->d.arrayexpr.elemtype;
-	int			nelems = op->d.arrayexpr.nelems;
+	Oid			element_type = op->arrayexpr.elemtype;
+	int			nelems = op->arrayexpr.nelems;
 	int			ndims = 0;
 	int			dims[MAXDIM];
 	int			lbs[MAXDIM];
@@ -3410,11 +3410,11 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
 	/* Set non-null as default */
 	*op->resnull = false;
 
-	if (!op->d.arrayexpr.multidims)
+	if (!op->arrayexpr.multidims)
 	{
 		/* Elements are presumably of scalar type */
-		Datum	   *dvalues = op->d.arrayexpr.elemvalues;
-		bool	   *dnulls = op->d.arrayexpr.elemnulls;
+		Datum	   *dvalues = op->arrayexpr.elemvalues;
+		bool	   *dnulls = op->arrayexpr.elemnulls;
 
 		/* setup for 1-D array of the given length */
 		ndims = 1;
@@ -3423,9 +3423,9 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
 
 		result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
 									element_type,
-									op->d.arrayexpr.elemlength,
-									op->d.arrayexpr.elembyval,
-									op->d.arrayexpr.elemalign);
+									op->arrayexpr.elemlength,
+									op->arrayexpr.elembyval,
+									op->arrayexpr.elemalign);
 	}
 	else
 	{
@@ -3460,8 +3460,8 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
 			ArrayType  *array;
 			int			this_ndims;
 
-			arraydatum = op->d.arrayexpr.elemvalues[elemoff];
-			eisnull = op->d.arrayexpr.elemnulls[elemoff];
+			arraydatum = op->arrayexpr.elemvalues[elemoff];
+			eisnull = op->arrayexpr.elemnulls[elemoff];
 
 			/* temporarily ignore null subarrays */
 			if (eisnull)
@@ -3626,12 +3626,12 @@ ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 	 * If it's binary-compatible, modify the element type in the array header,
 	 * but otherwise leave the array as we received it.
 	 */
-	if (op->d.arraycoerce.elemexprstate == NULL)
+	if (op->arraycoerce.elemexprstate == NULL)
 	{
 		/* Detoast input array if necessary, and copy in any case */
 		ArrayType  *array = DatumGetArrayTypePCopy(arraydatum);
 
-		ARR_ELEMTYPE(array) = op->d.arraycoerce.resultelemtype;
+		ARR_ELEMTYPE(array) = op->arraycoerce.resultelemtype;
 		*op->resvalue = PointerGetDatum(array);
 		return;
 	}
@@ -3640,17 +3640,17 @@ ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 	 * Use array_map to apply the sub-expression to each array element.
 	 */
 	*op->resvalue = array_map(arraydatum,
-							  op->d.arraycoerce.elemexprstate,
+							  op->arraycoerce.elemexprstate,
 							  econtext,
-							  op->d.arraycoerce.resultelemtype,
-							  op->d.arraycoerce.amstate);
+							  op->arraycoerce.resultelemtype,
+							  op->arraycoerce.amstate);
 }
 
 /*
  * Evaluate a ROW() expression.
  *
  * The individual columns have already been evaluated into
- * op->d.row.elemvalues[]/elemnulls[].
+ * op->row.elemvalues[]/elemnulls[].
  */
 void
 ExecEvalRow(ExprState *state, ExprEvalStep *op)
@@ -3658,9 +3658,9 @@ ExecEvalRow(ExprState *state, ExprEvalStep *op)
 	HeapTuple	tuple;
 
 	/* build tuple from evaluated field values */
-	tuple = heap_form_tuple(op->d.row.tupdesc,
-							op->d.row.elemvalues,
-							op->d.row.elemnulls);
+	tuple = heap_form_tuple(op->row.tupdesc,
+							op->row.elemvalues,
+							op->row.elemnulls);
 
 	*op->resvalue = HeapTupleGetDatum(tuple);
 	*op->resnull = false;
@@ -3670,15 +3670,15 @@ ExecEvalRow(ExprState *state, ExprEvalStep *op)
  * Evaluate GREATEST() or LEAST() expression (note this is *not* MIN()/MAX()).
  *
  * All of the to-be-compared expressions have already been evaluated into
- * op->d.minmax.values[]/nulls[].
+ * op->minmax.values[]/nulls[].
  */
 void
 ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
 {
-	Datum	   *values = op->d.minmax.values;
-	bool	   *nulls = op->d.minmax.nulls;
-	FunctionCallInfo fcinfo = op->d.minmax.fcinfo_data;
-	MinMaxOp	operator = op->d.minmax.op;
+	Datum	   *values = op->minmax.values;
+	bool	   *nulls = op->minmax.nulls;
+	FunctionCallInfo fcinfo = op->minmax.fcinfo_data;
+	MinMaxOp	operator = op->minmax.op;
 
 	/* set at initialization */
 	Assert(fcinfo->args[0].isnull == false);
@@ -3687,7 +3687,7 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
 	/* default to null result */
 	*op->resnull = true;
 
-	for (int off = 0; off < op->d.minmax.nelems; off++)
+	for (int off = 0; off < op->minmax.nelems; off++)
 	{
 		/* ignore NULL inputs */
 		if (nulls[off])
@@ -3728,7 +3728,7 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
 void
 ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
-	AttrNumber	fieldnum = op->d.fieldselect.fieldnum;
+	AttrNumber	fieldnum = op->fieldselect.fieldnum;
 	Datum		tupDatum;
 	HeapTupleHeader tuple;
 	Oid			tupType;
@@ -3775,13 +3775,13 @@ ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
 		/* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
 		/* As in CheckVarSlotCompatibility, we should but can't check typmod */
-		if (op->d.fieldselect.resulttype != attr->atttypid)
+		if (op->fieldselect.resulttype != attr->atttypid)
 			ereport(ERROR,
 					(errcode(ERRCODE_DATATYPE_MISMATCH),
 					 errmsg("attribute %d has wrong type", fieldnum),
 					 errdetail("Table has type %s, but query expects %s.",
 							   format_type_be(attr->atttypid),
-							   format_type_be(op->d.fieldselect.resulttype))));
+							   format_type_be(op->fieldselect.resulttype))));
 
 		/* extract the field */
 		*op->resvalue = expanded_record_get_field(erh, fieldnum,
@@ -3797,7 +3797,7 @@ ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
 		/* Lookup tupdesc if first time through or if type changes */
 		tupDesc = get_cached_rowtype(tupType, tupTypmod,
-									 &op->d.fieldselect.rowcache, NULL);
+									 &op->fieldselect.rowcache, NULL);
 
 		/*
 		 * Find field's attr record.  Note we don't support system columns
@@ -3821,13 +3821,13 @@ ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
 		/* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
 		/* As in CheckVarSlotCompatibility, we should but can't check typmod */
-		if (op->d.fieldselect.resulttype != attr->atttypid)
+		if (op->fieldselect.resulttype != attr->atttypid)
 			ereport(ERROR,
 					(errcode(ERRCODE_DATATYPE_MISMATCH),
 					 errmsg("attribute %d has wrong type", fieldnum),
 					 errdetail("Table has type %s, but query expects %s.",
 							   format_type_be(attr->atttypid),
-							   format_type_be(op->d.fieldselect.resulttype))));
+							   format_type_be(op->fieldselect.resulttype))));
 
 		/* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
 		tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
@@ -3856,8 +3856,8 @@ ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, ExprContext *econte
 	if (*op->resnull)
 	{
 		/* Convert null input tuple into an all-nulls row */
-		memset(op->d.fieldstore.nulls, true,
-			   op->d.fieldstore.ncolumns * sizeof(bool));
+		memset(op->fieldstore.nulls, true,
+			   op->fieldstore.ncolumns * sizeof(bool));
 	}
 	else
 	{
@@ -3882,17 +3882,17 @@ ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, ExprContext *econte
 		 * doing DatumGetHeapTupleHeader: that could do database access while
 		 * detoasting the datum.
 		 */
-		tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
-									 op->d.fieldstore.rowcache, NULL);
+		tupDesc = get_cached_rowtype(op->fieldstore.fstore->resulttype, -1,
+									 op->fieldstore.rowcache, NULL);
 
 		/* Check that current tupdesc doesn't have more fields than allocated */
-		if (unlikely(tupDesc->natts > op->d.fieldstore.ncolumns))
+		if (unlikely(tupDesc->natts > op->fieldstore.ncolumns))
 			elog(ERROR, "too many columns in composite type %u",
-				 op->d.fieldstore.fstore->resulttype);
+				 op->fieldstore.fstore->resulttype);
 
 		heap_deform_tuple(&tmptup, tupDesc,
-						  op->d.fieldstore.values,
-						  op->d.fieldstore.nulls);
+						  op->fieldstore.values,
+						  op->fieldstore.nulls);
 	}
 }
 
@@ -3907,12 +3907,12 @@ ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext
 	HeapTuple	tuple;
 
 	/* Lookup tupdesc (should be valid already) */
-	tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1,
-								 op->d.fieldstore.rowcache, NULL);
+	tupDesc = get_cached_rowtype(op->fieldstore.fstore->resulttype, -1,
+								 op->fieldstore.rowcache, NULL);
 
 	tuple = heap_form_tuple(tupDesc,
-							op->d.fieldstore.values,
-							op->d.fieldstore.nulls);
+							op->fieldstore.values,
+							op->fieldstore.nulls);
 
 	*op->resvalue = HeapTupleGetDatum(tuple);
 	*op->resnull = false;
@@ -3947,12 +3947,12 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext
 	 * pin them since type conversion functions could do catalog lookups and
 	 * hence cause cache invalidation.
 	 */
-	indesc = get_cached_rowtype(op->d.convert_rowtype.inputtype, -1,
-								op->d.convert_rowtype.incache,
+	indesc = get_cached_rowtype(op->convert_rowtype.inputtype, -1,
+								op->convert_rowtype.incache,
 								&changed);
 	IncrTupleDescRefCount(indesc);
-	outdesc = get_cached_rowtype(op->d.convert_rowtype.outputtype, -1,
-								 op->d.convert_rowtype.outcache,
+	outdesc = get_cached_rowtype(op->convert_rowtype.outputtype, -1,
+								 op->convert_rowtype.outcache,
 								 &changed);
 	IncrTupleDescRefCount(outdesc);
 
@@ -3974,7 +3974,7 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext
 		old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
 
 		/* prepare map from old to new attribute numbers */
-		op->d.convert_rowtype.map = convert_tuples_by_name(indesc, outdesc);
+		op->convert_rowtype.map = convert_tuples_by_name(indesc, outdesc);
 
 		MemoryContextSwitchTo(old_cxt);
 	}
@@ -3983,10 +3983,10 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext
 	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
 	tmptup.t_data = tuple;
 
-	if (op->d.convert_rowtype.map != NULL)
+	if (op->convert_rowtype.map != NULL)
 	{
 		/* Full conversion with attribute rearrangement needed */
-		result = execute_attr_map_tuple(&tmptup, op->d.convert_rowtype.map);
+		result = execute_attr_map_tuple(&tmptup, op->convert_rowtype.map);
 		/* Result already has appropriate composite-datum header fields */
 		*op->resvalue = HeapTupleGetDatum(result);
 	}
@@ -4022,9 +4022,9 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext
 void
 ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
 {
-	FunctionCallInfo fcinfo = op->d.scalararrayop.fcinfo_data;
-	bool		useOr = op->d.scalararrayop.useOr;
-	bool		strictfunc = op->d.scalararrayop.finfo->fn_strict;
+	FunctionCallInfo fcinfo = op->scalararrayop.fcinfo_data;
+	bool		useOr = op->scalararrayop.useOr;
+	bool		strictfunc = op->scalararrayop.finfo->fn_strict;
 	ArrayType  *arr;
 	int			nitems;
 	Datum		result;
@@ -4074,18 +4074,18 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
 	 * We arrange to look up info about the element type only once per series
 	 * of calls, assuming the element type doesn't change underneath us.
 	 */
-	if (op->d.scalararrayop.element_type != ARR_ELEMTYPE(arr))
+	if (op->scalararrayop.element_type != ARR_ELEMTYPE(arr))
 	{
 		get_typlenbyvalalign(ARR_ELEMTYPE(arr),
-							 &op->d.scalararrayop.typlen,
-							 &op->d.scalararrayop.typbyval,
-							 &op->d.scalararrayop.typalign);
-		op->d.scalararrayop.element_type = ARR_ELEMTYPE(arr);
+							 &op->scalararrayop.typlen,
+							 &op->scalararrayop.typbyval,
+							 &op->scalararrayop.typalign);
+		op->scalararrayop.element_type = ARR_ELEMTYPE(arr);
 	}
 
-	typlen = op->d.scalararrayop.typlen;
-	typbyval = op->d.scalararrayop.typbyval;
-	typalign = op->d.scalararrayop.typalign;
+	typlen = op->scalararrayop.typlen;
+	typbyval = op->scalararrayop.typbyval;
+	typalign = op->scalararrayop.typalign;
 
 	/* Initialize result appropriately depending on useOr */
 	result = BoolGetDatum(!useOr);
@@ -4125,7 +4125,7 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
 		else
 		{
 			fcinfo->isnull = false;
-			thisresult = op->d.scalararrayop.fn_addr(fcinfo);
+			thisresult = op->scalararrayop.fn_addr(fcinfo);
 		}
 
 		/* Combine results per OR or AND semantics */
@@ -4197,14 +4197,14 @@ saop_hash_element_match(struct saophash_hash *tb, Datum key1, Datum key2)
 	Datum		result;
 
 	ScalarArrayOpExprHashTable *elements_tab = (ScalarArrayOpExprHashTable *) tb->private_data;
-	FunctionCallInfo fcinfo = elements_tab->op->d.hashedscalararrayop.fcinfo_data;
+	FunctionCallInfo fcinfo = elements_tab->op->hashedscalararrayop.fcinfo_data;
 
 	fcinfo->args[0].value = key1;
 	fcinfo->args[0].isnull = false;
 	fcinfo->args[1].value = key2;
 	fcinfo->args[1].isnull = false;
 
-	result = elements_tab->op->d.hashedscalararrayop.finfo->fn_addr(fcinfo);
+	result = elements_tab->op->hashedscalararrayop.finfo->fn_addr(fcinfo);
 
 	return DatumGetBool(result);
 }
@@ -4225,10 +4225,10 @@ saop_hash_element_match(struct saophash_hash *tb, Datum key1, Datum key2)
 void
 ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
-	ScalarArrayOpExprHashTable *elements_tab = op->d.hashedscalararrayop.elements_tab;
-	FunctionCallInfo fcinfo = op->d.hashedscalararrayop.fcinfo_data;
-	bool		inclause = op->d.hashedscalararrayop.inclause;
-	bool		strictfunc = op->d.hashedscalararrayop.finfo->fn_strict;
+	ScalarArrayOpExprHashTable *elements_tab = op->hashedscalararrayop.elements_tab;
+	FunctionCallInfo fcinfo = op->hashedscalararrayop.fcinfo_data;
+	bool		inclause = op->hashedscalararrayop.inclause;
+	bool		strictfunc = op->hashedscalararrayop.finfo->fn_strict;
 	Datum		scalar = fcinfo->args[0].value;
 	bool		scalar_isnull = fcinfo->args[0].isnull;
 	Datum		result;
@@ -4263,7 +4263,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco
 		MemoryContext oldcontext;
 		ArrayType  *arr;
 
-		saop = op->d.hashedscalararrayop.saop;
+		saop = op->hashedscalararrayop.saop;
 
 		arr = DatumGetArrayTypeP(*op->resvalue);
 		nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
@@ -4278,7 +4278,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco
 		elements_tab = (ScalarArrayOpExprHashTable *)
 			palloc0(offsetof(ScalarArrayOpExprHashTable, hash_fcinfo_data) +
 					SizeForFunctionCallInfo(1));
-		op->d.hashedscalararrayop.elements_tab = elements_tab;
+		op->hashedscalararrayop.elements_tab = elements_tab;
 		elements_tab->op = op;
 
 		fmgr_info(saop->hashfuncid, &elements_tab->hash_finfo);
@@ -4339,7 +4339,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco
 		 * Remember if we had any nulls so that we know if we need to execute
 		 * non-strict functions with a null lhs value if no match is found.
 		 */
-		op->d.hashedscalararrayop.has_nulls = has_nulls;
+		op->hashedscalararrayop.has_nulls = has_nulls;
 	}
 
 	/* Check the hash to see if we have a match. */
@@ -4359,7 +4359,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco
 	 * hashtable, but instead marked if we found any when building the table
 	 * in has_nulls.
 	 */
-	if (!hashfound && op->d.hashedscalararrayop.has_nulls)
+	if (!hashfound && op->hashedscalararrayop.has_nulls)
 	{
 		if (strictfunc)
 		{
@@ -4385,7 +4385,7 @@ ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *eco
 			fcinfo->args[1].value = (Datum) 0;
 			fcinfo->args[1].isnull = true;
 
-			result = op->d.hashedscalararrayop.finfo->fn_addr(fcinfo);
+			result = op->hashedscalararrayop.finfo->fn_addr(fcinfo);
 			resultnull = fcinfo->isnull;
 
 			/*
@@ -4408,11 +4408,11 @@ void
 ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op)
 {
 	if (*op->resnull)
-		errsave((Node *) op->d.domaincheck.escontext,
+		errsave((Node *) op->domaincheck.escontext,
 				(errcode(ERRCODE_NOT_NULL_VIOLATION),
 				 errmsg("domain %s does not allow null values",
-						format_type_be(op->d.domaincheck.resulttype)),
-				 errdatatype(op->d.domaincheck.resulttype)));
+						format_type_be(op->domaincheck.resulttype)),
+				 errdatatype(op->domaincheck.resulttype)));
 }
 
 /*
@@ -4421,15 +4421,15 @@ ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op)
 void
 ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op)
 {
-	if (!*op->d.domaincheck.checknull &&
-		!DatumGetBool(*op->d.domaincheck.checkvalue))
-		errsave((Node *) op->d.domaincheck.escontext,
+	if (!*op->domaincheck.checknull &&
+		!DatumGetBool(*op->domaincheck.checkvalue))
+		errsave((Node *) op->domaincheck.escontext,
 				(errcode(ERRCODE_CHECK_VIOLATION),
 				 errmsg("value for domain %s violates check constraint \"%s\"",
-						format_type_be(op->d.domaincheck.resulttype),
-						op->d.domaincheck.constraintname),
-				 errdomainconstraint(op->d.domaincheck.resulttype,
-									 op->d.domaincheck.constraintname)));
+						format_type_be(op->domaincheck.resulttype),
+						op->domaincheck.constraintname),
+				 errdomainconstraint(op->domaincheck.resulttype,
+									 op->domaincheck.constraintname)));
 }
 
 /*
@@ -4441,7 +4441,7 @@ ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op)
 void
 ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 {
-	XmlExpr    *xexpr = op->d.xmlexpr.xexpr;
+	XmlExpr    *xexpr = op->xmlexpr.xexpr;
 	Datum		value;
 
 	*op->resnull = true;		/* until we get a result */
@@ -4451,8 +4451,8 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 	{
 		case IS_XMLCONCAT:
 			{
-				Datum	   *argvalue = op->d.xmlexpr.argvalue;
-				bool	   *argnull = op->d.xmlexpr.argnull;
+				Datum	   *argvalue = op->xmlexpr.argvalue;
+				bool	   *argnull = op->xmlexpr.argnull;
 				List	   *values = NIL;
 
 				for (int i = 0; i < list_length(xexpr->args); i++)
@@ -4471,8 +4471,8 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
 		case IS_XMLFOREST:
 			{
-				Datum	   *argvalue = op->d.xmlexpr.named_argvalue;
-				bool	   *argnull = op->d.xmlexpr.named_argnull;
+				Datum	   *argvalue = op->xmlexpr.named_argvalue;
+				bool	   *argnull = op->xmlexpr.named_argnull;
 				StringInfoData buf;
 				ListCell   *lc;
 				ListCell   *lc2;
@@ -4513,17 +4513,17 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
 		case IS_XMLELEMENT:
 			*op->resvalue = PointerGetDatum(xmlelement(xexpr,
-													   op->d.xmlexpr.named_argvalue,
-													   op->d.xmlexpr.named_argnull,
-													   op->d.xmlexpr.argvalue,
-													   op->d.xmlexpr.argnull));
+													   op->xmlexpr.named_argvalue,
+													   op->xmlexpr.named_argnull,
+													   op->xmlexpr.argvalue,
+													   op->xmlexpr.argnull));
 			*op->resnull = false;
 			break;
 
 		case IS_XMLPARSE:
 			{
-				Datum	   *argvalue = op->d.xmlexpr.argvalue;
-				bool	   *argnull = op->d.xmlexpr.argnull;
+				Datum	   *argvalue = op->xmlexpr.argvalue;
+				bool	   *argnull = op->xmlexpr.argnull;
 				text	   *data;
 				bool		preserve_whitespace;
 
@@ -4557,11 +4557,11 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
 				if (xexpr->args)
 				{
-					isnull = op->d.xmlexpr.argnull[0];
+					isnull = op->xmlexpr.argnull[0];
 					if (isnull)
 						arg = NULL;
 					else
-						arg = DatumGetTextPP(op->d.xmlexpr.argvalue[0]);
+						arg = DatumGetTextPP(op->xmlexpr.argvalue[0]);
 				}
 				else
 				{
@@ -4578,8 +4578,8 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
 		case IS_XMLROOT:
 			{
-				Datum	   *argvalue = op->d.xmlexpr.argvalue;
-				bool	   *argnull = op->d.xmlexpr.argnull;
+				Datum	   *argvalue = op->xmlexpr.argvalue;
+				bool	   *argnull = op->xmlexpr.argnull;
 				xmltype    *data;
 				text	   *version;
 				int			standalone;
@@ -4608,8 +4608,8 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
 		case IS_XMLSERIALIZE:
 			{
-				Datum	   *argvalue = op->d.xmlexpr.argvalue;
-				bool	   *argnull = op->d.xmlexpr.argnull;
+				Datum	   *argvalue = op->xmlexpr.argvalue;
+				bool	   *argnull = op->xmlexpr.argnull;
 
 				/* argument type is known to be xml */
 				Assert(list_length(xexpr->args) == 1);
@@ -4628,8 +4628,8 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
 		case IS_DOCUMENT:
 			{
-				Datum	   *argvalue = op->d.xmlexpr.argvalue;
-				bool	   *argnull = op->d.xmlexpr.argnull;
+				Datum	   *argvalue = op->xmlexpr.argvalue;
+				bool	   *argnull = op->xmlexpr.argnull;
 
 				/* optional argument is known to be xml */
 				Assert(list_length(xexpr->args) == 1);
@@ -4658,7 +4658,7 @@ ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
 						ExprContext *econtext)
 {
 	Datum		res;
-	JsonConstructorExprState *jcstate = op->d.json_constructor.jcstate;
+	JsonConstructorExprState *jcstate = op->json_constructor.jcstate;
 	JsonConstructorExpr *ctor = jcstate->constructor;
 	bool		is_jsonb = ctor->returning->format->format_type == JS_FORMAT_JSONB;
 	bool		isnull = false;
@@ -4734,7 +4734,7 @@ ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
 void
 ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op)
 {
-	JsonIsPredicate *pred = op->d.is_json.pred;
+	JsonIsPredicate *pred = op->is_json.pred;
 	Datum		js = *op->resvalue;
 	Oid			exprtype;
 	bool		res;
@@ -4818,7 +4818,7 @@ ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op)
 
 /*
  * Evaluate a jsonpath against a document, both of which must have been
- * evaluated and their values saved in op->d.jsonexpr.jsestate.
+ * evaluated and their values saved in op->jsonexpr.jsestate.
  *
  * If an error occurs during JsonPath* evaluation or when coercing its result
  * to the RETURNING type, JsonExprState.error is set to true, provided the
@@ -4829,13 +4829,13 @@ ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op)
  *
  * Return value is the step address to be performed next.  It will be one of
  * jump_error, jump_empty, jump_eval_coercion, or jump_end, all given in
- * op->d.jsonexpr.jsestate.
+ * op->jsonexpr.jsestate.
  */
 int
 ExecEvalJsonExprPath(ExprState *state, ExprEvalStep *op,
 					 ExprContext *econtext)
 {
-	JsonExprState *jsestate = op->d.jsonexpr.jsestate;
+	JsonExprState *jsestate = op->jsonexpr.jsestate;
 	JsonExpr   *jsexpr = jsestate->jsexpr;
 	Datum		item;
 	JsonPath   *path;
@@ -5112,7 +5112,7 @@ void
 ExecEvalJsonCoercion(ExprState *state, ExprEvalStep *op,
 					 ExprContext *econtext)
 {
-	ErrorSaveContext *escontext = op->d.jsonexpr_coercion.escontext;
+	ErrorSaveContext *escontext = op->jsonexpr_coercion.escontext;
 
 	/*
 	 * Prepare to call json_populate_type() to coerce the boolean result of
@@ -5124,15 +5124,15 @@ ExecEvalJsonCoercion(ExprState *state, ExprEvalStep *op,
 	 * for integer and domains thereof as it seems common to use those types
 	 * for EXISTS columns in JSON_TABLE().
 	 */
-	if (op->d.jsonexpr_coercion.exists_coerce)
+	if (op->jsonexpr_coercion.exists_coerce)
 	{
-		if (op->d.jsonexpr_coercion.exists_cast_to_int)
+		if (op->jsonexpr_coercion.exists_cast_to_int)
 		{
 			/* Check domain constraints if any. */
-			if (op->d.jsonexpr_coercion.exists_check_domain &&
+			if (op->jsonexpr_coercion.exists_check_domain &&
 				!domain_check_safe(*op->resvalue, *op->resnull,
-								   op->d.jsonexpr_coercion.targettype,
-								   &op->d.jsonexpr_coercion.json_coercion_cache,
+								   op->jsonexpr_coercion.targettype,
+								   &op->jsonexpr_coercion.json_coercion_cache,
 								   econtext->ecxt_per_query_memory,
 								   (Node *) escontext))
 			{
@@ -5151,12 +5151,12 @@ ExecEvalJsonCoercion(ExprState *state, ExprEvalStep *op,
 	}
 
 	*op->resvalue = json_populate_type(*op->resvalue, JSONBOID,
-									   op->d.jsonexpr_coercion.targettype,
-									   op->d.jsonexpr_coercion.targettypmod,
-									   &op->d.jsonexpr_coercion.json_coercion_cache,
+									   op->jsonexpr_coercion.targettype,
+									   op->jsonexpr_coercion.targettypmod,
+									   &op->jsonexpr_coercion.json_coercion_cache,
 									   econtext->ecxt_per_query_memory,
 									   op->resnull,
-									   op->d.jsonexpr_coercion.omit_quotes,
+									   op->jsonexpr_coercion.omit_quotes,
 									   (Node *) escontext);
 }
 
@@ -5191,7 +5191,7 @@ GetJsonBehaviorValueString(JsonBehavior *behavior)
 void
 ExecEvalJsonCoercionFinish(ExprState *state, ExprEvalStep *op)
 {
-	JsonExprState *jsestate = op->d.jsonexpr.jsestate;
+	JsonExprState *jsestate = op->jsonexpr.jsestate;
 
 	if (SOFT_ERROR_OCCURRED(&jsestate->escontext))
 	{
@@ -5249,7 +5249,7 @@ ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op)
 	Bitmapset  *grouped_cols = aggstate->grouped_cols;
 	ListCell   *lc;
 
-	foreach(lc, op->d.grouping_func.clauses)
+	foreach(lc, op->grouping_func.clauses)
 	{
 		int			attnum = lfirst_int(lc);
 
@@ -5308,7 +5308,7 @@ ExecEvalMergeSupportFunc(ExprState *state, ExprEvalStep *op,
 void
 ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
-	SubPlanState *sstate = op->d.subplan.sstate;
+	SubPlanState *sstate = op->subplan.sstate;
 
 	/* could potentially be nested, so make sure there's enough stack */
 	check_stack_depth();
@@ -5325,7 +5325,7 @@ ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 void
 ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 {
-	Var		   *variable = op->d.wholerow.var;
+	Var		   *variable = op->wholerow.var;
 	TupleTableSlot *slot = NULL;
 	TupleDesc	output_tupdesc;
 	MemoryContext oldcontext;
@@ -5389,8 +5389,8 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 	}
 
 	/* Apply the junkfilter if any */
-	if (op->d.wholerow.junkFilter != NULL)
-		slot = ExecFilterJunk(op->d.wholerow.junkFilter, slot);
+	if (op->wholerow.junkFilter != NULL)
+		slot = ExecFilterJunk(op->wholerow.junkFilter, slot);
 
 	/*
 	 * If first time through, obtain tuple descriptor and check compatibility.
@@ -5399,10 +5399,10 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 	 * initialization phase, but due to using slots that's currently not
 	 * feasible.
 	 */
-	if (op->d.wholerow.first)
+	if (op->wholerow.first)
 	{
 		/* optimistically assume we don't need slow path */
-		op->d.wholerow.slow = false;
+		op->wholerow.slow = false;
 
 		/*
 		 * If the Var identifies a named composite type, we must check that
@@ -5461,7 +5461,7 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 
 				if (vattr->attlen != sattr->attlen ||
 					vattr->attalign != sattr->attalign)
-					op->d.wholerow.slow = true; /* need to check for nulls */
+					op->wholerow.slow = true;	/* need to check for nulls */
 			}
 
 			/*
@@ -5520,9 +5520,9 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 		}
 
 		/* Bless the tupdesc if needed, and save it in the execution state */
-		op->d.wholerow.tupdesc = BlessTupleDesc(output_tupdesc);
+		op->wholerow.tupdesc = BlessTupleDesc(output_tupdesc);
 
-		op->d.wholerow.first = false;
+		op->wholerow.first = false;
 	}
 
 	/*
@@ -5531,11 +5531,11 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 	 */
 	slot_getallattrs(slot);
 
-	if (op->d.wholerow.slow)
+	if (op->wholerow.slow)
 	{
 		/* Check to see if any dropped attributes are non-null */
 		TupleDesc	tupleDesc = slot->tts_tupleDescriptor;
-		TupleDesc	var_tupdesc = op->d.wholerow.tupdesc;
+		TupleDesc	var_tupdesc = op->wholerow.tupdesc;
 
 		Assert(var_tupdesc->natts == tupleDesc->natts);
 
@@ -5571,11 +5571,11 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 	/*
 	 * Label the datum with the composite type info we identified before.
 	 *
-	 * (Note: we could skip doing this by passing op->d.wholerow.tupdesc to
-	 * the tuple build step; but that seems a tad risky so let's not.)
+	 * (Note: we could skip doing this by passing op->wholerow.tupdesc to the
+	 * tuple build step; but that seems a tad risky so let's not.)
 	 */
-	HeapTupleHeaderSetTypeId(dtuple, op->d.wholerow.tupdesc->tdtypeid);
-	HeapTupleHeaderSetTypMod(dtuple, op->d.wholerow.tupdesc->tdtypmod);
+	HeapTupleHeaderSetTypeId(dtuple, op->wholerow.tupdesc->tdtypeid);
+	HeapTupleHeaderSetTypMod(dtuple, op->wholerow.tupdesc->tdtypmod);
 
 	*op->resvalue = PointerGetDatum(dtuple);
 	*op->resnull = false;
@@ -5588,9 +5588,9 @@ ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
 	Datum		d;
 
 	/* OLD/NEW system attribute is NULL if OLD/NEW row is NULL */
-	if ((op->d.var.varreturningtype == VAR_RETURNING_OLD &&
+	if ((op->var.varreturningtype == VAR_RETURNING_OLD &&
 		 state->flags & EEO_FLAG_OLD_IS_NULL) ||
-		(op->d.var.varreturningtype == VAR_RETURNING_NEW &&
+		(op->var.varreturningtype == VAR_RETURNING_NEW &&
 		 state->flags & EEO_FLAG_NEW_IS_NULL))
 	{
 		*op->resvalue = (Datum) 0;
@@ -5600,7 +5600,7 @@ ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
 
 	/* slot_getsysattr has sufficient defenses against bad attnums */
 	d = slot_getsysattr(slot,
-						op->d.var.attnum,
+						op->var.attnum,
 						op->resnull);
 	*op->resvalue = d;
 	/* this ought to be unreachable, but it's cheap enough to check */
@@ -5808,8 +5808,8 @@ void
 ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op,
 							 ExprContext *econtext)
 {
-	AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
-	int			setno = op->d.agg_trans.setno;
+	AggStatePerTrans pertrans = op->agg_trans.pertrans;
+	int			setno = op->agg_trans.setno;
 
 	tuplesort_putdatum(pertrans->sortstates[setno],
 					   *op->resvalue, *op->resnull);
@@ -5822,8 +5822,8 @@ void
 ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op,
 							 ExprContext *econtext)
 {
-	AggStatePerTrans pertrans = op->d.agg_trans.pertrans;
-	int			setno = op->d.agg_trans.setno;
+	AggStatePerTrans pertrans = op->agg_trans.pertrans;
+	int			setno = op->agg_trans.setno;
 
 	ExecClearTuple(pertrans->sortslot);
 	pertrans->sortslot->tts_nvalid = pertrans->numInputs;
diff --git a/src/backend/utils/adt/arraysubs.c b/src/backend/utils/adt/arraysubs.c
index 2940fb8e8d7..ca8f1647c89 100644
--- a/src/backend/utils/adt/arraysubs.c
+++ b/src/backend/utils/adt/arraysubs.c
@@ -182,7 +182,7 @@ array_subscript_check_subscripts(ExprState *state,
 								 ExprEvalStep *op,
 								 ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref_subscript.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 
 	/* Process upper subscripts */
@@ -238,7 +238,7 @@ array_subscript_fetch(ExprState *state,
 					  ExprEvalStep *op,
 					  ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 
 	/* Should not get here if source array (or any subscript) is null */
@@ -266,7 +266,7 @@ array_subscript_fetch_slice(ExprState *state,
 							ExprEvalStep *op,
 							ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 
 	/* Should not get here if source array (or any subscript) is null */
@@ -296,7 +296,7 @@ array_subscript_assign(ExprState *state,
 					   ExprEvalStep *op,
 					   ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 	Datum		arraySource = *op->resvalue;
 
@@ -346,7 +346,7 @@ array_subscript_assign_slice(ExprState *state,
 							 ExprEvalStep *op,
 							 ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 	Datum		arraySource = *op->resvalue;
 
@@ -401,7 +401,7 @@ array_subscript_fetch_old(ExprState *state,
 						  ExprEvalStep *op,
 						  ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 
 	if (*op->resnull)
@@ -441,7 +441,7 @@ array_subscript_fetch_old_slice(ExprState *state,
 								ExprEvalStep *op,
 								ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace;
 
 	if (*op->resnull)
diff --git a/src/backend/utils/adt/jsonbsubs.c b/src/backend/utils/adt/jsonbsubs.c
index e8626d3b4fc..8211de23d59 100644
--- a/src/backend/utils/adt/jsonbsubs.c
+++ b/src/backend/utils/adt/jsonbsubs.c
@@ -176,7 +176,7 @@ jsonb_subscript_check_subscripts(ExprState *state,
 								 ExprEvalStep *op,
 								 ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref_subscript.state;
 	JsonbSubWorkspace *workspace = (JsonbSubWorkspace *) sbsrefstate->workspace;
 
 	/*
@@ -236,7 +236,7 @@ jsonb_subscript_fetch(ExprState *state,
 					  ExprEvalStep *op,
 					  ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	JsonbSubWorkspace *workspace = (JsonbSubWorkspace *) sbsrefstate->workspace;
 	Jsonb	   *jsonbSource;
 
@@ -262,7 +262,7 @@ jsonb_subscript_assign(ExprState *state,
 					   ExprEvalStep *op,
 					   ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 	JsonbSubWorkspace *workspace = (JsonbSubWorkspace *) sbsrefstate->workspace;
 	Jsonb	   *jsonbSource;
 	JsonbValue	replacevalue;
@@ -324,7 +324,7 @@ jsonb_subscript_fetch_old(ExprState *state,
 						  ExprEvalStep *op,
 						  ExprContext *econtext)
 {
-	SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
+	SubscriptingRefState *sbsrefstate = op->sbsref.state;
 
 	if (*op->resnull)
 	{
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 75366203706..3852dcaa5c0 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -769,7 +769,7 @@ typedef struct ExprEvalStep
 			void	   *json_coercion_cache;
 			ErrorSaveContext *escontext;
 		}			jsonexpr_coercion;
-	}			d;
+	};
 } ExprEvalStep;
 
 /* Enforce the size rule given in the comment above */
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index d19425b7a71..81417f85c99 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -6481,25 +6481,25 @@ plpgsql_param_compile(ParamListInfo params, Param *param,
 		bool		isvarlena = (((PLpgSQL_var *) datum)->datatype->typlen == -1);
 
 		if (isvarlena && dno == expr->target_param && expr->expr_simple_expr)
-			scratch.d.cparam.paramfunc = plpgsql_param_eval_var_check;
+			scratch.cparam.paramfunc = plpgsql_param_eval_var_check;
 		else if (isvarlena)
-			scratch.d.cparam.paramfunc = plpgsql_param_eval_var_ro;
+			scratch.cparam.paramfunc = plpgsql_param_eval_var_ro;
 		else
-			scratch.d.cparam.paramfunc = plpgsql_param_eval_var;
+			scratch.cparam.paramfunc = plpgsql_param_eval_var;
 	}
 	else if (datum->dtype == PLPGSQL_DTYPE_RECFIELD)
-		scratch.d.cparam.paramfunc = plpgsql_param_eval_recfield;
+		scratch.cparam.paramfunc = plpgsql_param_eval_recfield;
 	else if (datum->dtype == PLPGSQL_DTYPE_PROMISE)
 	{
 		if (((PLpgSQL_var *) datum)->datatype->typlen == -1)
-			scratch.d.cparam.paramfunc = plpgsql_param_eval_generic_ro;
+			scratch.cparam.paramfunc = plpgsql_param_eval_generic_ro;
 		else
-			scratch.d.cparam.paramfunc = plpgsql_param_eval_generic;
+			scratch.cparam.paramfunc = plpgsql_param_eval_generic;
 	}
 	else if (datum->dtype == PLPGSQL_DTYPE_REC)
-		scratch.d.cparam.paramfunc = plpgsql_param_eval_generic_ro;
+		scratch.cparam.paramfunc = plpgsql_param_eval_generic_ro;
 	else
-		scratch.d.cparam.paramfunc = plpgsql_param_eval_generic;
+		scratch.cparam.paramfunc = plpgsql_param_eval_generic;
 
 	/*
 	 * Note: it's tempting to use paramarg to store the estate pointer and
@@ -6509,10 +6509,10 @@ plpgsql_param_compile(ParamListInfo params, Param *param,
 	 * pointers to the PLpgSQL_expr as well as this specific Param, to support
 	 * plpgsql_param_eval_var_check().
 	 */
-	scratch.d.cparam.paramarg = expr;
-	scratch.d.cparam.paramarg2 = param;
-	scratch.d.cparam.paramid = param->paramid;
-	scratch.d.cparam.paramtype = param->paramtype;
+	scratch.cparam.paramarg = expr;
+	scratch.cparam.paramarg2 = param;
+	scratch.cparam.paramid = param->paramid;
+	scratch.cparam.paramtype = param->paramtype;
 	ExprEvalPushStep(state, &scratch);
 }
 
@@ -6535,7 +6535,7 @@ plpgsql_param_eval_var_check(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_var *var;
 
 	/* fetch back the hook data */
@@ -6554,15 +6554,15 @@ plpgsql_param_eval_var_check(ExprState *state, ExprEvalStep *op,
 	if (!var->isnull &&
 		VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(var->value)))
 	{
-		PLpgSQL_expr *expr = (PLpgSQL_expr *) op->d.cparam.paramarg;
-		Param	   *param = (Param *) op->d.cparam.paramarg2;
+		PLpgSQL_expr *expr = (PLpgSQL_expr *) op->cparam.paramarg;
+		Param	   *param = (Param *) op->cparam.paramarg2;
 
 		/*
 		 * We might have already figured this out while evaluating some other
 		 * Param referencing the same variable, so check expr_rwopt first.
 		 */
 		if (expr->expr_rwopt == PLPGSQL_RWOPT_UNKNOWN)
-			exec_check_rw_parameter(expr, op->d.cparam.paramid);
+			exec_check_rw_parameter(expr, op->cparam.paramid);
 
 		/*
 		 * Update the callback pointer to match what we decided to do, so that
@@ -6576,27 +6576,27 @@ plpgsql_param_eval_var_check(ExprState *state, ExprEvalStep *op,
 				break;
 			case PLPGSQL_RWOPT_NOPE:
 				/* Force the value to read-only in all future executions */
-				op->d.cparam.paramfunc = plpgsql_param_eval_var_ro;
+				op->cparam.paramfunc = plpgsql_param_eval_var_ro;
 				plpgsql_param_eval_var_ro(state, op, econtext);
 				break;
 			case PLPGSQL_RWOPT_TRANSFER:
 				/* There can be only one matching Param in this case */
 				Assert(param == expr->expr_rw_param);
 				/* When the value is read/write, transfer to exec context */
-				op->d.cparam.paramfunc = plpgsql_param_eval_var_transfer;
+				op->cparam.paramfunc = plpgsql_param_eval_var_transfer;
 				plpgsql_param_eval_var_transfer(state, op, econtext);
 				break;
 			case PLPGSQL_RWOPT_INPLACE:
 				if (param == expr->expr_rw_param)
 				{
 					/* When the value is read/write, deliver it as-is */
-					op->d.cparam.paramfunc = plpgsql_param_eval_var;
+					op->cparam.paramfunc = plpgsql_param_eval_var;
 					plpgsql_param_eval_var(state, op, econtext);
 				}
 				else
 				{
 					/* Not the optimizable reference, so force to read-only */
-					op->d.cparam.paramfunc = plpgsql_param_eval_var_ro;
+					op->cparam.paramfunc = plpgsql_param_eval_var_ro;
 					plpgsql_param_eval_var_ro(state, op, econtext);
 				}
 				break;
@@ -6613,7 +6613,7 @@ plpgsql_param_eval_var_check(ExprState *state, ExprEvalStep *op,
 	*op->resnull = var->isnull;
 
 	/* safety check -- an assertion should be sufficient */
-	Assert(var->datatype->typoid == op->d.cparam.paramtype);
+	Assert(var->datatype->typoid == op->cparam.paramtype);
 }
 
 /*
@@ -6632,7 +6632,7 @@ plpgsql_param_eval_var_transfer(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_var *var;
 
 	/* fetch back the hook data */
@@ -6673,7 +6673,7 @@ plpgsql_param_eval_var_transfer(ExprState *state, ExprEvalStep *op,
 	}
 
 	/* safety check -- an assertion should be sufficient */
-	Assert(var->datatype->typoid == op->d.cparam.paramtype);
+	Assert(var->datatype->typoid == op->cparam.paramtype);
 }
 
 /*
@@ -6688,7 +6688,7 @@ plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_var *var;
 
 	/* fetch back the hook data */
@@ -6705,7 +6705,7 @@ plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op,
 	*op->resnull = var->isnull;
 
 	/* safety check -- an assertion should be sufficient */
-	Assert(var->datatype->typoid == op->d.cparam.paramtype);
+	Assert(var->datatype->typoid == op->cparam.paramtype);
 }
 
 /*
@@ -6720,7 +6720,7 @@ plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_var *var;
 
 	/* fetch back the hook data */
@@ -6742,7 +6742,7 @@ plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op,
 	*op->resnull = var->isnull;
 
 	/* safety check -- an assertion should be sufficient */
-	Assert(var->datatype->typoid == op->d.cparam.paramtype);
+	Assert(var->datatype->typoid == op->cparam.paramtype);
 }
 
 /*
@@ -6757,7 +6757,7 @@ plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_recfield *recfield;
 	PLpgSQL_rec *rec;
 	ExpandedRecordHeader *erh;
@@ -6808,13 +6808,13 @@ plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op,
 											  op->resnull);
 
 	/* safety check -- needed for, eg, record fields */
-	if (unlikely(recfield->finfo.ftypeid != op->d.cparam.paramtype))
+	if (unlikely(recfield->finfo.ftypeid != op->cparam.paramtype))
 		ereport(ERROR,
 				(errcode(ERRCODE_DATATYPE_MISMATCH),
 				 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
-						op->d.cparam.paramid,
+						op->cparam.paramid,
 						format_type_be(recfield->finfo.ftypeid),
-						format_type_be(op->d.cparam.paramtype))));
+						format_type_be(op->cparam.paramtype))));
 }
 
 /*
@@ -6829,7 +6829,7 @@ plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_datum *datum;
 	Oid			datumtype;
 	int32		datumtypmod;
@@ -6848,13 +6848,13 @@ plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op,
 					op->resvalue, op->resnull);
 
 	/* safety check -- needed for, eg, record fields */
-	if (unlikely(datumtype != op->d.cparam.paramtype))
+	if (unlikely(datumtype != op->cparam.paramtype))
 		ereport(ERROR,
 				(errcode(ERRCODE_DATATYPE_MISMATCH),
 				 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
-						op->d.cparam.paramid,
+						op->cparam.paramid,
 						format_type_be(datumtype),
-						format_type_be(op->d.cparam.paramtype))));
+						format_type_be(op->cparam.paramtype))));
 }
 
 /*
@@ -6869,7 +6869,7 @@ plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op,
 {
 	ParamListInfo params;
 	PLpgSQL_execstate *estate;
-	int			dno = op->d.cparam.paramid - 1;
+	int			dno = op->cparam.paramid - 1;
 	PLpgSQL_datum *datum;
 	Oid			datumtype;
 	int32		datumtypmod;
@@ -6888,13 +6888,13 @@ plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op,
 					op->resvalue, op->resnull);
 
 	/* safety check -- needed for, eg, record fields */
-	if (unlikely(datumtype != op->d.cparam.paramtype))
+	if (unlikely(datumtype != op->cparam.paramtype))
 		ereport(ERROR,
 				(errcode(ERRCODE_DATATYPE_MISMATCH),
 				 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
-						op->d.cparam.paramid,
+						op->cparam.paramid,
 						format_type_be(datumtype),
-						format_type_be(op->d.cparam.paramtype))));
+						format_type_be(op->cparam.paramtype))));
 
 	/* force the value to read-only */
 	*op->resvalue = MakeExpandedObjectReadOnly(*op->resvalue,
-- 
2.51.0

From d15e0fd28601ff163e356a5cb7ae946f8d50d4ad Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email-masked]>
Date: Mon, 22 Sep 2025 14:47:49 +0200
Subject: [PATCH 23/23] C11 anonymous unions [json]

---
 contrib/hstore/hstore_io.c              |  22 +-
 contrib/jsonb_plperl/jsonb_plperl.c     |  28 +-
 contrib/jsonb_plpython/jsonb_plpython.c |  22 +-
 src/backend/executor/execExprInterp.c   |  24 +-
 src/backend/utils/adt/jsonb.c           | 157 ++++++------
 src/backend/utils/adt/jsonb_gin.c       |  38 +--
 src/backend/utils/adt/jsonb_op.c        |  12 +-
 src/backend/utils/adt/jsonb_util.c      | 240 ++++++++---------
 src/backend/utils/adt/jsonbsubs.c       |   6 +-
 src/backend/utils/adt/jsonfuncs.c       | 328 ++++++++++++------------
 src/backend/utils/adt/jsonpath.c        | 170 ++++++------
 src/backend/utils/adt/jsonpath_exec.c   | 248 +++++++++---------
 src/backend/utils/adt/jsonpath_gram.y   |  56 ++--
 src/include/utils/jsonb.h               |   2 +-
 src/include/utils/jsonpath.h            |   4 +-
 15 files changed, 678 insertions(+), 679 deletions(-)

diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index 9c53877c4a5..3673f2bb6dd 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -1450,8 +1450,8 @@ hstore_to_jsonb(PG_FUNCTION_ARGS)
 					val;
 
 		key.type = jbvString;
-		key.val.string.len = HSTORE_KEYLEN(entries, i);
-		key.val.string.val = HSTORE_KEY(entries, base, i);
+		key.string.len = HSTORE_KEYLEN(entries, i);
+		key.string.val = HSTORE_KEY(entries, base, i);
 
 		(void) pushJsonbValue(&state, WJB_KEY, &key);
 
@@ -1462,8 +1462,8 @@ hstore_to_jsonb(PG_FUNCTION_ARGS)
 		else
 		{
 			val.type = jbvString;
-			val.val.string.len = HSTORE_VALLEN(entries, i);
-			val.val.string.val = HSTORE_VAL(entries, base, i);
+			val.string.len = HSTORE_VALLEN(entries, i);
+			val.string.val = HSTORE_VAL(entries, base, i);
 		}
 		(void) pushJsonbValue(&state, WJB_VALUE, &val);
 	}
@@ -1496,8 +1496,8 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS)
 					val;
 
 		key.type = jbvString;
-		key.val.string.len = HSTORE_KEYLEN(entries, i);
-		key.val.string.val = HSTORE_KEY(entries, base, i);
+		key.string.len = HSTORE_KEYLEN(entries, i);
+		key.string.val = HSTORE_KEY(entries, base, i);
 
 		(void) pushJsonbValue(&state, WJB_KEY, &key);
 
@@ -1510,13 +1510,13 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS)
 				 *(HSTORE_VAL(entries, base, i)) == 't')
 		{
 			val.type = jbvBool;
-			val.val.boolean = true;
+			val.boolean = true;
 		}
 		else if (HSTORE_VALLEN(entries, i) == 1 &&
 				 *(HSTORE_VAL(entries, base, i)) == 'f')
 		{
 			val.type = jbvBool;
-			val.val.boolean = false;
+			val.boolean = false;
 		}
 		else
 		{
@@ -1532,13 +1532,13 @@ hstore_to_jsonb_loose(PG_FUNCTION_ARGS)
 										   CStringGetDatum(tmp.data),
 										   ObjectIdGetDatum(InvalidOid),
 										   Int32GetDatum(-1));
-				val.val.numeric = DatumGetNumeric(numd);
+				val.numeric = DatumGetNumeric(numd);
 			}
 			else
 			{
 				val.type = jbvString;
-				val.val.string.len = HSTORE_VALLEN(entries, i);
-				val.val.string.val = HSTORE_VAL(entries, base, i);
+				val.string.len = HSTORE_VALLEN(entries, i);
+				val.string.val = HSTORE_VAL(entries, base, i);
 			}
 		}
 		(void) pushJsonbValue(&state, WJB_VALUE, &val);
diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c
index c02e2d41af1..2b5e16c22f6 100644
--- a/contrib/jsonb_plperl/jsonb_plperl.c
+++ b/contrib/jsonb_plperl/jsonb_plperl.c
@@ -24,12 +24,12 @@ JsonbValue_to_SV(JsonbValue *jbv)
 	switch (jbv->type)
 	{
 		case jbvBinary:
-			return Jsonb_to_SV(jbv->val.binary.data);
+			return Jsonb_to_SV(jbv->binary.data);
 
 		case jbvNumeric:
 			{
 				char	   *str = DatumGetCString(DirectFunctionCall1(numeric_out,
-																	  NumericGetDatum(jbv->val.numeric)));
+																	  NumericGetDatum(jbv->numeric)));
 				SV		   *result = newSVnv(SvNV(cstr2sv(str)));
 
 				pfree(str);
@@ -38,8 +38,8 @@ JsonbValue_to_SV(JsonbValue *jbv)
 
 		case jbvString:
 			{
-				char	   *str = pnstrdup(jbv->val.string.val,
-										   jbv->val.string.len);
+				char	   *str = pnstrdup(jbv->string.val,
+										   jbv->string.len);
 				SV		   *result = cstr2sv(str);
 
 				pfree(str);
@@ -47,7 +47,7 @@ JsonbValue_to_SV(JsonbValue *jbv)
 			}
 
 		case jbvBool:
-			return newSVnv(SvNV(jbv->val.boolean ? &PL_sv_yes : &PL_sv_no));
+			return newSVnv(SvNV(jbv->boolean ? &PL_sv_yes : &PL_sv_no));
 
 		case jbvNull:
 			return newSV(0);
@@ -72,7 +72,7 @@ Jsonb_to_SV(JsonbContainer *jsonb)
 	switch (r)
 	{
 		case WJB_BEGIN_ARRAY:
-			if (v.val.array.rawScalar)
+			if (v.array.rawScalar)
 			{
 				JsonbValue	tmp;
 
@@ -112,7 +112,7 @@ Jsonb_to_SV(JsonbContainer *jsonb)
 							SV		   *value = JsonbValue_to_SV(&val);
 
 							(void) hv_store(hv,
-											v.val.string.val, v.val.string.len,
+											v.string.val, v.string.len,
 											value, 0);
 						}
 					}
@@ -164,8 +164,8 @@ HV_to_JsonbValue(HV *obj, JsonbParseState **jsonb_state)
 
 	while ((val = hv_iternextsv(obj, &kstr, &klen)))
 	{
-		key.val.string.val = pnstrdup(kstr, klen);
-		key.val.string.len = klen;
+		key.string.val = pnstrdup(kstr, klen);
+		key.string.len = klen;
 		pushJsonbValue(jsonb_state, WJB_KEY, &key);
 		(void) SV_to_JsonbValue(val, jsonb_state, false);
 	}
@@ -207,7 +207,7 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
 				const char *strval = SvPV_nolen(in);
 
 				out.type = jbvNumeric;
-				out.val.numeric =
+				out.numeric =
 					DatumGetNumeric(DirectFunctionCall3(numeric_in,
 														CStringGetDatum(strval),
 														ObjectIdGetDatum(InvalidOid),
@@ -218,7 +218,7 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
 				IV			ival = SvIV(in);
 
 				out.type = jbvNumeric;
-				out.val.numeric = int64_to_numeric(ival);
+				out.numeric = int64_to_numeric(ival);
 			}
 			else if (SvNOK(in))
 			{
@@ -240,15 +240,15 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
 							 errmsg("cannot convert NaN to jsonb")));
 
 				out.type = jbvNumeric;
-				out.val.numeric =
+				out.numeric =
 					DatumGetNumeric(DirectFunctionCall1(float8_numeric,
 														Float8GetDatum(nval)));
 			}
 			else if (SvPOK(in))
 			{
 				out.type = jbvString;
-				out.val.string.val = sv2cstr(in);
-				out.val.string.len = strlen(out.val.string.val);
+				out.string.val = sv2cstr(in);
+				out.string.len = strlen(out.string.val);
 			}
 			else
 			{
diff --git a/contrib/jsonb_plpython/jsonb_plpython.c b/contrib/jsonb_plpython/jsonb_plpython.c
index 9383615abbf..10a3be28fcb 100644
--- a/contrib/jsonb_plpython/jsonb_plpython.c
+++ b/contrib/jsonb_plpython/jsonb_plpython.c
@@ -70,7 +70,7 @@ PLyUnicode_FromJsonbValue(JsonbValue *jbv)
 {
 	Assert(jbv->type == jbvString);
 
-	return PLyUnicode_FromStringAndSize(jbv->val.string.val, jbv->val.string.len);
+	return PLyUnicode_FromStringAndSize(jbv->string.val, jbv->string.len);
 }
 
 /*
@@ -82,8 +82,8 @@ static void
 PLyUnicode_ToJsonbValue(PyObject *obj, JsonbValue *jbvElem)
 {
 	jbvElem->type = jbvString;
-	jbvElem->val.string.val = PLyObject_AsString(obj);
-	jbvElem->val.string.len = strlen(jbvElem->val.string.val);
+	jbvElem->string.val = PLyObject_AsString(obj);
+	jbvElem->string.len = strlen(jbvElem->string.val);
 }
 
 /*
@@ -100,14 +100,14 @@ PLyObject_FromJsonbValue(JsonbValue *jsonbValue)
 			Py_RETURN_NONE;
 
 		case jbvBinary:
-			return PLyObject_FromJsonbContainer(jsonbValue->val.binary.data);
+			return PLyObject_FromJsonbContainer(jsonbValue->binary.data);
 
 		case jbvNumeric:
 			{
 				Datum		num;
 				char	   *str;
 
-				num = NumericGetDatum(jsonbValue->val.numeric);
+				num = NumericGetDatum(jsonbValue->numeric);
 				str = DatumGetCString(DirectFunctionCall1(numeric_out, num));
 
 				return PyObject_CallFunction(decimal_constructor, "s", str);
@@ -117,7 +117,7 @@ PLyObject_FromJsonbValue(JsonbValue *jsonbValue)
 			return PLyUnicode_FromJsonbValue(jsonbValue);
 
 		case jbvBool:
-			if (jsonbValue->val.boolean)
+			if (jsonbValue->boolean)
 				Py_RETURN_TRUE;
 			else
 				Py_RETURN_FALSE;
@@ -147,7 +147,7 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
 	switch (r)
 	{
 		case WJB_BEGIN_ARRAY:
-			if (v.val.array.rawScalar)
+			if (v.array.rawScalar)
 			{
 				JsonbValue	tmp;
 
@@ -288,8 +288,8 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
 			if (key == Py_None)
 			{
 				jbvKey.type = jbvString;
-				jbvKey.val.string.len = 0;
-				jbvKey.val.string.val = "";
+				jbvKey.string.len = 0;
+				jbvKey.string.val = "";
 			}
 			else
 			{
@@ -396,7 +396,7 @@ PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum)
 				 errmsg("cannot convert infinity to jsonb")));
 
 	jbvNum->type = jbvNumeric;
-	jbvNum->val.numeric = num;
+	jbvNum->numeric = num;
 
 	return jbvNum;
 }
@@ -433,7 +433,7 @@ PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_ele
 	else if (PyBool_Check(obj))
 	{
 		out->type = jbvBool;
-		out->val.boolean = (obj == Py_True);
+		out->boolean = (obj == Py_True);
 	}
 	else if (PyNumber_Check(obj))
 		out = PLyNumber_ToJsonbValue(obj, out);
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 51f498bd79a..5958324000c 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -5047,42 +5047,42 @@ ExecGetJsonValueItemString(JsonbValue *item, bool *resnull)
 
 		case jbvString:
 			{
-				char	   *str = palloc(item->val.string.len + 1);
+				char	   *str = palloc(item->string.len + 1);
 
-				memcpy(str, item->val.string.val, item->val.string.len);
-				str[item->val.string.len] = '\0';
+				memcpy(str, item->string.val, item->string.len);
+				str[item->string.len] = '\0';
 				return str;
 			}
 
 		case jbvNumeric:
 			return DatumGetCString(DirectFunctionCall1(numeric_out,
-													   NumericGetDatum(item->val.numeric)));
+													   NumericGetDatum(item->numeric)));
 
 		case jbvBool:
 			return DatumGetCString(DirectFunctionCall1(boolout,
-													   BoolGetDatum(item->val.boolean)));
+													   BoolGetDatum(item->boolean)));
 
 		case jbvDatetime:
-			switch (item->val.datetime.typid)
+			switch (item->datetime.typid)
 			{
 				case DATEOID:
 					return DatumGetCString(DirectFunctionCall1(date_out,
-															   item->val.datetime.value));
+															   item->datetime.value));
 				case TIMEOID:
 					return DatumGetCString(DirectFunctionCall1(time_out,
-															   item->val.datetime.value));
+															   item->datetime.value));
 				case TIMETZOID:
 					return DatumGetCString(DirectFunctionCall1(timetz_out,
-															   item->val.datetime.value));
+															   item->datetime.value));
 				case TIMESTAMPOID:
 					return DatumGetCString(DirectFunctionCall1(timestamp_out,
-															   item->val.datetime.value));
+															   item->datetime.value));
 				case TIMESTAMPTZOID:
 					return DatumGetCString(DirectFunctionCall1(timestamptz_out,
-															   item->val.datetime.value));
+															   item->datetime.value));
 				default:
 					elog(ERROR, "unexpected jsonb datetime type oid %u",
-						 item->val.datetime.typid);
+						 item->datetime.typid);
 			}
 			break;
 
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index da94d424d61..ae9562cefc9 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -182,7 +182,7 @@ JsonbTypeName(JsonbValue *val)
 	switch (val->type)
 	{
 		case jbvBinary:
-			return JsonbContainerTypeName(val->val.binary.data);
+			return JsonbContainerTypeName(val->binary.data);
 		case jbvObject:
 			return "object";
 		case jbvArray:
@@ -196,7 +196,7 @@ JsonbTypeName(JsonbValue *val)
 		case jbvNull:
 			return "null";
 		case jbvDatetime:
-			switch (val->val.datetime.typid)
+			switch (val->datetime.typid)
 			{
 				case DATEOID:
 					return "date";
@@ -210,7 +210,7 @@ JsonbTypeName(JsonbValue *val)
 					return "timestamp with time zone";
 				default:
 					elog(ERROR, "unrecognized jsonb value datetime type: %d",
-						 val->val.datetime.typid);
+						 val->datetime.typid);
 			}
 			return "unknown";
 		default:
@@ -335,10 +335,10 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
 
 	Assert(fname != NULL);
 	v.type = jbvString;
-	v.val.string.len = strlen(fname);
-	if (!checkStringLen(v.val.string.len, _state->escontext))
+	v.string.len = strlen(fname);
+	if (!checkStringLen(v.string.len, _state->escontext))
 		return JSON_SEM_ACTION_FAILED;
-	v.val.string.val = fname;
+	v.string.val = fname;
 
 	_state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
 
@@ -354,15 +354,15 @@ jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
 			appendBinaryStringInfo(out, "null", 4);
 			break;
 		case jbvString:
-			escape_json_with_len(out, scalarVal->val.string.val, scalarVal->val.string.len);
+			escape_json_with_len(out, scalarVal->string.val, scalarVal->string.len);
 			break;
 		case jbvNumeric:
 			appendStringInfoString(out,
 								   DatumGetCString(DirectFunctionCall1(numeric_out,
-																	   PointerGetDatum(scalarVal->val.numeric))));
+																	   PointerGetDatum(scalarVal->numeric))));
 			break;
 		case jbvBool:
-			if (scalarVal->val.boolean)
+			if (scalarVal->boolean)
 				appendBinaryStringInfo(out, "true", 4);
 			else
 				appendBinaryStringInfo(out, "false", 5);
@@ -388,10 +388,10 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
 		case JSON_TOKEN_STRING:
 			Assert(token != NULL);
 			v.type = jbvString;
-			v.val.string.len = strlen(token);
-			if (!checkStringLen(v.val.string.len, _state->escontext))
+			v.string.len = strlen(token);
+			if (!checkStringLen(v.string.len, _state->escontext))
 				return JSON_SEM_ACTION_FAILED;
-			v.val.string.val = token;
+			v.string.val = token;
 			break;
 		case JSON_TOKEN_NUMBER:
 
@@ -406,15 +406,15 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
 											 _state->escontext,
 											 &numd))
 				return JSON_SEM_ACTION_FAILED;
-			v.val.numeric = DatumGetNumeric(numd);
+			v.numeric = DatumGetNumeric(numd);
 			break;
 		case JSON_TOKEN_TRUE:
 			v.type = jbvBool;
-			v.val.boolean = true;
+			v.boolean = true;
 			break;
 		case JSON_TOKEN_FALSE:
 			v.type = jbvBool;
-			v.val.boolean = false;
+			v.boolean = false;
 			break;
 		case JSON_TOKEN_NULL:
 			v.type = jbvNull;
@@ -431,8 +431,8 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
 		JsonbValue	va;
 
 		va.type = jbvArray;
-		va.val.array.rawScalar = true;
-		va.val.array.nElems = 1;
+		va.array.rawScalar = true;
+		va.array.nElems = 1;
 
 		_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va);
 		_state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
@@ -525,7 +525,7 @@ JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool
 				if (!first)
 					appendBinaryStringInfo(out, ", ", ispaces);
 
-				if (!v.val.array.rawScalar)
+				if (!v.array.rawScalar)
 				{
 					add_indent(out, use_indent && !last_was_key, level);
 					appendStringInfoCharMacro(out, '[');
@@ -681,13 +681,13 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
 				{
 					outputstr = DatumGetBool(val) ? "true" : "false";
 					jb.type = jbvString;
-					jb.val.string.len = strlen(outputstr);
-					jb.val.string.val = outputstr;
+					jb.string.len = strlen(outputstr);
+					jb.string.val = outputstr;
 				}
 				else
 				{
 					jb.type = jbvBool;
-					jb.val.boolean = DatumGetBool(val);
+					jb.boolean = DatumGetBool(val);
 				}
 				break;
 			case JSONTYPE_NUMERIC:
@@ -696,8 +696,8 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
 				{
 					/* always quote keys */
 					jb.type = jbvString;
-					jb.val.string.len = strlen(outputstr);
-					jb.val.string.val = outputstr;
+					jb.string.len = strlen(outputstr);
+					jb.string.val = outputstr;
 				}
 				else
 				{
@@ -717,34 +717,34 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
 												   CStringGetDatum(outputstr),
 												   ObjectIdGetDatum(InvalidOid),
 												   Int32GetDatum(-1));
-						jb.val.numeric = DatumGetNumeric(numd);
+						jb.numeric = DatumGetNumeric(numd);
 						pfree(outputstr);
 					}
 					else
 					{
 						jb.type = jbvString;
-						jb.val.string.len = strlen(outputstr);
-						jb.val.string.val = outputstr;
+						jb.string.len = strlen(outputstr);
+						jb.string.val = outputstr;
 					}
 				}
 				break;
 			case JSONTYPE_DATE:
 				jb.type = jbvString;
-				jb.val.string.val = JsonEncodeDateTime(NULL, val,
-													   DATEOID, NULL);
-				jb.val.string.len = strlen(jb.val.string.val);
+				jb.string.val = JsonEncodeDateTime(NULL, val,
+												   DATEOID, NULL);
+				jb.string.len = strlen(jb.string.val);
 				break;
 			case JSONTYPE_TIMESTAMP:
 				jb.type = jbvString;
-				jb.val.string.val = JsonEncodeDateTime(NULL, val,
-													   TIMESTAMPOID, NULL);
-				jb.val.string.len = strlen(jb.val.string.val);
+				jb.string.val = JsonEncodeDateTime(NULL, val,
+												   TIMESTAMPOID, NULL);
+				jb.string.len = strlen(jb.string.val);
 				break;
 			case JSONTYPE_TIMESTAMPTZ:
 				jb.type = jbvString;
-				jb.val.string.val = JsonEncodeDateTime(NULL, val,
-													   TIMESTAMPTZOID, NULL);
-				jb.val.string.len = strlen(jb.val.string.val);
+				jb.string.val = JsonEncodeDateTime(NULL, val,
+												   TIMESTAMPTZOID, NULL);
+				jb.string.len = strlen(jb.string.val);
 				break;
 			case JSONTYPE_CAST:
 			case JSONTYPE_JSON:
@@ -806,9 +806,9 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
 			default:
 				outputstr = OidOutputFunctionCall(outfuncoid, val);
 				jb.type = jbvString;
-				jb.val.string.len = strlen(outputstr);
-				(void) checkStringLen(jb.val.string.len, NULL);
-				jb.val.string.val = outputstr;
+				jb.string.len = strlen(outputstr);
+				(void) checkStringLen(jb.string.len, NULL);
+				jb.string.val = outputstr;
 				break;
 		}
 	}
@@ -826,8 +826,8 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
 		JsonbValue	va;
 
 		va.type = jbvArray;
-		va.val.array.rawScalar = true;
-		va.val.array.nElems = 1;
+		va.array.rawScalar = true;
+		va.array.nElems = 1;
 
 		result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, &va);
 		result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
@@ -980,8 +980,8 @@ composite_to_jsonb(Datum composite, JsonbInState *result)
 
 		v.type = jbvString;
 		/* don't need checkStringLen here - can't exceed maximum name length */
-		v.val.string.len = strlen(attname);
-		v.val.string.val = attname;
+		v.string.len = strlen(attname);
+		v.string.val = attname;
 
 		result->res = pushJsonbValue(&result->parseState, WJB_KEY, &v);
 
@@ -1337,8 +1337,8 @@ jsonb_object(PG_FUNCTION_ARGS)
 
 		v.type = jbvString;
 
-		v.val.string.len = len;
-		v.val.string.val = str;
+		v.string.len = len;
+		v.string.val = str;
 
 		(void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
 
@@ -1353,8 +1353,8 @@ jsonb_object(PG_FUNCTION_ARGS)
 
 			v.type = jbvString;
 
-			v.val.string.len = len;
-			v.val.string.val = str;
+			v.string.len = len;
+			v.string.val = str;
 		}
 
 		(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
@@ -1427,8 +1427,8 @@ jsonb_object_two_arg(PG_FUNCTION_ARGS)
 
 		v.type = jbvString;
 
-		v.val.string.len = len;
-		v.val.string.val = str;
+		v.string.len = len;
+		v.string.val = str;
 
 		(void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
 
@@ -1443,8 +1443,8 @@ jsonb_object_two_arg(PG_FUNCTION_ARGS)
 
 			v.type = jbvString;
 
-			v.val.string.len = len;
-			v.val.string.val = str;
+			v.string.len = len;
+			v.string.val = str;
 		}
 
 		(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
@@ -1571,7 +1571,7 @@ jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
 		switch (type)
 		{
 			case WJB_BEGIN_ARRAY:
-				if (v.val.array.rawScalar)
+				if (v.array.rawScalar)
 					single_scalar = true;
 				else
 					result->res = pushJsonbValue(&result->parseState,
@@ -1593,17 +1593,17 @@ jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
 				if (v.type == jbvString)
 				{
 					/* copy string values in the aggregate context */
-					char	   *buf = palloc(v.val.string.len + 1);
+					char	   *buf = palloc(v.string.len + 1);
 
-					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
-					v.val.string.val = buf;
+					snprintf(buf, v.string.len + 1, "%s", v.string.val);
+					v.string.val = buf;
 				}
 				else if (v.type == jbvNumeric)
 				{
 					/* same for numeric */
-					v.val.numeric =
+					v.numeric =
 						DatumGetNumeric(DirectFunctionCall1(numeric_uplus,
-															NumericGetDatum(v.val.numeric)));
+															NumericGetDatum(v.numeric)));
 				}
 				result->res = pushJsonbValue(&result->parseState,
 											 type, &v);
@@ -1787,17 +1787,17 @@ jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo,
 		switch (type)
 		{
 			case WJB_BEGIN_ARRAY:
-				if (!v.val.array.rawScalar)
+				if (!v.array.rawScalar)
 					elog(ERROR, "unexpected structure for key");
 				break;
 			case WJB_ELEM:
 				if (v.type == jbvString)
 				{
 					/* copy string values in the aggregate context */
-					char	   *buf = palloc(v.val.string.len + 1);
+					char	   *buf = palloc(v.string.len + 1);
 
-					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
-					v.val.string.val = buf;
+					snprintf(buf, v.string.len + 1, "%s", v.string.val);
+					v.string.val = buf;
 				}
 				else
 				{
@@ -1841,7 +1841,7 @@ jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo,
 		switch (type)
 		{
 			case WJB_BEGIN_ARRAY:
-				if (v.val.array.rawScalar)
+				if (v.array.rawScalar)
 					single_scalar = true;
 				else
 					result->res = pushJsonbValue(&result->parseState,
@@ -1863,17 +1863,17 @@ jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo,
 				if (v.type == jbvString)
 				{
 					/* copy string values in the aggregate context */
-					char	   *buf = palloc(v.val.string.len + 1);
+					char	   *buf = palloc(v.string.len + 1);
 
-					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
-					v.val.string.val = buf;
+					snprintf(buf, v.string.len + 1, "%s", v.string.val);
+					v.string.val = buf;
 				}
 				else if (v.type == jbvNumeric)
 				{
 					/* same for numeric */
-					v.val.numeric =
+					v.numeric =
 						DatumGetNumeric(DirectFunctionCall1(numeric_uplus,
-															NumericGetDatum(v.val.numeric)));
+															NumericGetDatum(v.numeric)));
 				}
 				result->res = pushJsonbValue(&result->parseState,
 											 single_scalar ? WJB_VALUE : type,
@@ -1986,7 +1986,7 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
 
 	tok = JsonbIteratorNext(&it, &tmp, true);
 	Assert(tok == WJB_BEGIN_ARRAY);
-	Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
+	Assert(tmp.array.nElems == 1 && tmp.array.rawScalar);
 
 	tok = JsonbIteratorNext(&it, res, true);
 	Assert(tok == WJB_ELEM);
@@ -2054,7 +2054,7 @@ jsonb_bool(PG_FUNCTION_ARGS)
 
 	PG_FREE_IF_COPY(in, 0);
 
-	PG_RETURN_BOOL(v.val.boolean);
+	PG_RETURN_BOOL(v.boolean);
 }
 
 Datum
@@ -2077,10 +2077,9 @@ jsonb_numeric(PG_FUNCTION_ARGS)
 		cannotCastJsonbValue(v.type, "numeric");
 
 	/*
-	 * v.val.numeric points into jsonb body, so we need to make a copy to
-	 * return
+	 * v.numeric points into jsonb body, so we need to make a copy to return
 	 */
-	retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
+	retValue = DatumGetNumericCopy(NumericGetDatum(v.numeric));
 
 	PG_FREE_IF_COPY(in, 0);
 
@@ -2107,7 +2106,7 @@ jsonb_int2(PG_FUNCTION_ARGS)
 		cannotCastJsonbValue(v.type, "smallint");
 
 	retValue = DirectFunctionCall1(numeric_int2,
-								   NumericGetDatum(v.val.numeric));
+								   NumericGetDatum(v.numeric));
 
 	PG_FREE_IF_COPY(in, 0);
 
@@ -2134,7 +2133,7 @@ jsonb_int4(PG_FUNCTION_ARGS)
 		cannotCastJsonbValue(v.type, "integer");
 
 	retValue = DirectFunctionCall1(numeric_int4,
-								   NumericGetDatum(v.val.numeric));
+								   NumericGetDatum(v.numeric));
 
 	PG_FREE_IF_COPY(in, 0);
 
@@ -2161,7 +2160,7 @@ jsonb_int8(PG_FUNCTION_ARGS)
 		cannotCastJsonbValue(v.type, "bigint");
 
 	retValue = DirectFunctionCall1(numeric_int8,
-								   NumericGetDatum(v.val.numeric));
+								   NumericGetDatum(v.numeric));
 
 	PG_FREE_IF_COPY(in, 0);
 
@@ -2188,7 +2187,7 @@ jsonb_float4(PG_FUNCTION_ARGS)
 		cannotCastJsonbValue(v.type, "real");
 
 	retValue = DirectFunctionCall1(numeric_float4,
-								   NumericGetDatum(v.val.numeric));
+								   NumericGetDatum(v.numeric));
 
 	PG_FREE_IF_COPY(in, 0);
 
@@ -2215,7 +2214,7 @@ jsonb_float8(PG_FUNCTION_ARGS)
 		cannotCastJsonbValue(v.type, "double precision");
 
 	retValue = DirectFunctionCall1(numeric_float8,
-								   NumericGetDatum(v.val.numeric));
+								   NumericGetDatum(v.numeric));
 
 	PG_FREE_IF_COPY(in, 0);
 
@@ -2235,12 +2234,12 @@ JsonbUnquote(Jsonb *jb)
 		(void) JsonbExtractScalar(&jb->root, &v);
 
 		if (v.type == jbvString)
-			return pnstrdup(v.val.string.val, v.val.string.len);
+			return pnstrdup(v.string.val, v.string.len);
 		else if (v.type == jbvBool)
-			return pstrdup(v.val.boolean ? "true" : "false");
+			return pstrdup(v.boolean ? "true" : "false");
 		else if (v.type == jbvNumeric)
 			return DatumGetCString(DirectFunctionCall1(numeric_out,
-													   PointerGetDatum(v.val.numeric)));
+													   PointerGetDatum(v.numeric)));
 		else if (v.type == jbvNull)
 			return pstrdup("null");
 		else
diff --git a/src/backend/utils/adt/jsonb_gin.c b/src/backend/utils/adt/jsonb_gin.c
index 9b56248cf0b..4b7cb39e96d 100644
--- a/src/backend/utils/adt/jsonb_gin.c
+++ b/src/backend/utils/adt/jsonb_gin.c
@@ -104,7 +104,7 @@ struct JsonPathGinNode
 								 * nodes after entries output */
 		Datum		entryDatum; /* path hash or key name/scalar, valid for
 								 * ENTRY nodes before entries output */
-	}			val;
+	};
 	JsonPathGinNode *args[FLEXIBLE_ARRAY_MEMBER];	/* valid for OR and AND
 													 * nodes */
 };
@@ -333,7 +333,7 @@ jsonb_path_ops__add_path_item(JsonPathGinPath *path, JsonPathItem *jsp)
 				JsonbValue	jbv;
 
 				jbv.type = jbvString;
-				jbv.val.string.val = jspGetString(jsp, &jbv.val.string.len);
+				jbv.string.val = jspGetString(jsp, &jbv.string.len);
 
 				JsonbHashScalarValue(&jbv, &path->hash);
 				return true;
@@ -355,7 +355,7 @@ make_jsp_entry_node(Datum entry)
 	JsonPathGinNode *node = palloc(offsetof(JsonPathGinNode, args));
 
 	node->type = JSP_GIN_ENTRY;
-	node->val.entryDatum = entry;
+	node->entryDatum = entry;
 
 	return node;
 }
@@ -373,7 +373,7 @@ make_jsp_expr_node(JsonPathGinNodeType type, int nargs)
 								   sizeof(node->args[0]) * nargs);
 
 	node->type = type;
-	node->val.nargs = nargs;
+	node->nargs = nargs;
 
 	return node;
 }
@@ -687,18 +687,18 @@ extract_jsp_bool_expr(JsonPathGinContext *cxt, JsonPathGinPath path,
 						break;
 					case jpiBool:
 						scalar.type = jbvBool;
-						scalar.val.boolean = !!*scalar_item->content.value.data;
+						scalar.boolean = !!*scalar_item->value.data;
 						break;
 					case jpiNumeric:
 						scalar.type = jbvNumeric;
-						scalar.val.numeric =
-							(Numeric) scalar_item->content.value.data;
+						scalar.numeric =
+							(Numeric) scalar_item->value.data;
 						break;
 					case jpiString:
 						scalar.type = jbvString;
-						scalar.val.string.val = scalar_item->content.value.data;
-						scalar.val.string.len =
-							scalar_item->content.value.datalen;
+						scalar.string.val = scalar_item->value.data;
+						scalar.string.len =
+							scalar_item->value.datalen;
 						break;
 					default:
 						elog(ERROR, "invalid scalar jsonpath item type: %d",
@@ -724,7 +724,7 @@ emit_jsp_gin_entries(JsonPathGinNode *node, GinEntries *entries)
 	{
 		case JSP_GIN_ENTRY:
 			/* replace datum with its index in the array */
-			node->val.entryIndex = add_gin_entry(entries, node->val.entryDatum);
+			node->entryIndex = add_gin_entry(entries, node->entryDatum);
 			break;
 
 		case JSP_GIN_OR:
@@ -732,7 +732,7 @@ emit_jsp_gin_entries(JsonPathGinNode *node, GinEntries *entries)
 			{
 				int			i;
 
-				for (i = 0; i < node->val.nargs; i++)
+				for (i = 0; i < node->nargs; i++)
 					emit_jsp_gin_entries(node->args[i], entries);
 
 				break;
@@ -806,7 +806,7 @@ execute_jsp_gin_node(JsonPathGinNode *node, void *check, bool ternary)
 	{
 		case JSP_GIN_AND:
 			res = GIN_TRUE;
-			for (i = 0; i < node->val.nargs; i++)
+			for (i = 0; i < node->nargs; i++)
 			{
 				v = execute_jsp_gin_node(node->args[i], check, ternary);
 				if (v == GIN_FALSE)
@@ -818,7 +818,7 @@ execute_jsp_gin_node(JsonPathGinNode *node, void *check, bool ternary)
 
 		case JSP_GIN_OR:
 			res = GIN_FALSE;
-			for (i = 0; i < node->val.nargs; i++)
+			for (i = 0; i < node->nargs; i++)
 			{
 				v = execute_jsp_gin_node(node->args[i], check, ternary);
 				if (v == GIN_TRUE)
@@ -830,7 +830,7 @@ execute_jsp_gin_node(JsonPathGinNode *node, void *check, bool ternary)
 
 		case JSP_GIN_ENTRY:
 			{
-				int			index = node->val.entryIndex;
+				int			index = node->entryIndex;
 
 				if (ternary)
 					return ((GinTernaryValue *) check)[index];
@@ -1375,7 +1375,7 @@ make_scalar_key(const JsonbValue *scalarVal, bool is_key)
 		case jbvBool:
 			Assert(!is_key);
 			item = make_text_key(JGINFLAG_BOOL,
-								 scalarVal->val.boolean ? "t" : "f", 1);
+								 scalarVal->boolean ? "t" : "f", 1);
 			break;
 		case jbvNumeric:
 			Assert(!is_key);
@@ -1390,14 +1390,14 @@ make_scalar_key(const JsonbValue *scalarVal, bool is_key)
 			 * storing a "union" type in the GIN B-Tree, and indexing Jsonb
 			 * strings takes precedence.
 			 */
-			cstr = numeric_normalize(scalarVal->val.numeric);
+			cstr = numeric_normalize(scalarVal->numeric);
 			item = make_text_key(JGINFLAG_NUM, cstr, strlen(cstr));
 			pfree(cstr);
 			break;
 		case jbvString:
 			item = make_text_key(is_key ? JGINFLAG_KEY : JGINFLAG_STR,
-								 scalarVal->val.string.val,
-								 scalarVal->val.string.len);
+								 scalarVal->string.val,
+								 scalarVal->string.len);
 			break;
 		default:
 			elog(ERROR, "unrecognized jsonb scalar type: %d", scalarVal->type);
diff --git a/src/backend/utils/adt/jsonb_op.c b/src/backend/utils/adt/jsonb_op.c
index 51d38e321fb..df4552b0620 100644
--- a/src/backend/utils/adt/jsonb_op.c
+++ b/src/backend/utils/adt/jsonb_op.c
@@ -32,8 +32,8 @@ jsonb_exists(PG_FUNCTION_ARGS)
 	 * top level.  No recursion occurs.
 	 */
 	kval.type = jbvString;
-	kval.val.string.val = VARDATA_ANY(key);
-	kval.val.string.len = VARSIZE_ANY_EXHDR(key);
+	kval.string.val = VARDATA_ANY(key);
+	kval.string.len = VARSIZE_ANY_EXHDR(key);
 
 	v = findJsonbValueFromContainer(&jb->root,
 									JB_FOBJECT | JB_FARRAY,
@@ -63,8 +63,8 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
 
 		strVal.type = jbvString;
 		/* We rely on the array elements not being toasted */
-		strVal.val.string.val = VARDATA_ANY(DatumGetPointer(key_datums[i]));
-		strVal.val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i]));
+		strVal.string.val = VARDATA_ANY(DatumGetPointer(key_datums[i]));
+		strVal.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i]));
 
 		if (findJsonbValueFromContainer(&jb->root,
 										JB_FOBJECT | JB_FARRAY,
@@ -96,8 +96,8 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
 
 		strVal.type = jbvString;
 		/* We rely on the array elements not being toasted */
-		strVal.val.string.val = VARDATA_ANY(DatumGetPointer(key_datums[i]));
-		strVal.val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i]));
+		strVal.string.val = VARDATA_ANY(DatumGetPointer(key_datums[i]));
+		strVal.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(key_datums[i]));
 
 		if (findJsonbValueFromContainer(&jb->root,
 										JB_FOBJECT | JB_FARRAY,
diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c
index 82b807d067a..998125f6f5a 100644
--- a/src/backend/utils/adt/jsonb_util.c
+++ b/src/backend/utils/adt/jsonb_util.c
@@ -72,8 +72,8 @@ void
 JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val)
 {
 	val->type = jbvBinary;
-	val->val.binary.data = &jsonb->root;
-	val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
+	val->binary.data = &jsonb->root;
+	val->binary.len = VARSIZE(jsonb) - VARHDRSZ;
 }
 
 /*
@@ -101,8 +101,8 @@ JsonbValueToJsonb(JsonbValue *val)
 		JsonbValue	scalarArray;
 
 		scalarArray.type = jbvArray;
-		scalarArray.val.array.rawScalar = true;
-		scalarArray.val.array.nElems = 1;
+		scalarArray.array.rawScalar = true;
+		scalarArray.array.nElems = 1;
 
 		pushJsonbValue(&pstate, WJB_BEGIN_ARRAY, &scalarArray);
 		pushJsonbValue(&pstate, WJB_ELEM, val);
@@ -117,9 +117,9 @@ JsonbValueToJsonb(JsonbValue *val)
 	else
 	{
 		Assert(val->type == jbvBinary);
-		out = palloc(VARHDRSZ + val->val.binary.len);
-		SET_VARSIZE(out, VARHDRSZ + val->val.binary.len);
-		memcpy(VARDATA(out), val->val.binary.data, val->val.binary.len);
+		out = palloc(VARHDRSZ + val->binary.len);
+		SET_VARSIZE(out, VARHDRSZ + val->binary.len);
+		memcpy(VARDATA(out), val->binary.data, val->binary.len);
 	}
 
 	return out;
@@ -244,8 +244,8 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
 						 * general type-based comparisons to apply, and as far
 						 * as we're concerned a pseudo array is just a scalar.
 						 */
-						if (va.val.array.rawScalar != vb.val.array.rawScalar)
-							res = (va.val.array.rawScalar) ? -1 : 1;
+						if (va.array.rawScalar != vb.array.rawScalar)
+							res = (va.array.rawScalar) ? -1 : 1;
 
 						/*
 						 * There should be an "else" here, to prevent us from
@@ -253,12 +253,12 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
 						 * order now, so there is a mild anomaly that an empty
 						 * top level array sorts less than null.
 						 */
-						if (va.val.array.nElems != vb.val.array.nElems)
-							res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1;
+						if (va.array.nElems != vb.array.nElems)
+							res = (va.array.nElems > vb.array.nElems) ? 1 : -1;
 						break;
 					case jbvObject:
-						if (va.val.object.nPairs != vb.val.object.nPairs)
-							res = (va.val.object.nPairs > vb.val.object.nPairs) ? 1 : -1;
+						if (va.object.nPairs != vb.object.nPairs)
+							res = (va.object.nPairs > vb.object.nPairs) ? 1 : -1;
 						break;
 					case jbvBinary:
 						elog(ERROR, "unexpected jbvBinary value");
@@ -381,8 +381,8 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
 		/* Object key passed by caller must be a string */
 		Assert(key->type == jbvString);
 
-		return getKeyJsonValueFromContainer(container, key->val.string.val,
-											key->val.string.len, NULL);
+		return getKeyJsonValueFromContainer(container, key->string.val,
+											key->string.len, NULL);
 	}
 
 	/* Not found */
@@ -516,32 +516,32 @@ fillJsonbValue(JsonbContainer *container, int index,
 	else if (JBE_ISSTRING(entry))
 	{
 		result->type = jbvString;
-		result->val.string.val = base_addr + offset;
-		result->val.string.len = getJsonbLength(container, index);
-		Assert(result->val.string.len >= 0);
+		result->string.val = base_addr + offset;
+		result->string.len = getJsonbLength(container, index);
+		Assert(result->string.len >= 0);
 	}
 	else if (JBE_ISNUMERIC(entry))
 	{
 		result->type = jbvNumeric;
-		result->val.numeric = (Numeric) (base_addr + INTALIGN(offset));
+		result->numeric = (Numeric) (base_addr + INTALIGN(offset));
 	}
 	else if (JBE_ISBOOL_TRUE(entry))
 	{
 		result->type = jbvBool;
-		result->val.boolean = true;
+		result->boolean = true;
 	}
 	else if (JBE_ISBOOL_FALSE(entry))
 	{
 		result->type = jbvBool;
-		result->val.boolean = false;
+		result->boolean = false;
 	}
 	else
 	{
 		Assert(JBE_ISCONTAINER(entry));
 		result->type = jbvBinary;
 		/* Remove alignment padding from data pointer and length */
-		result->val.binary.data = (JsonbContainer *) (base_addr + INTALIGN(offset));
-		result->val.binary.len = getJsonbLength(container, index) -
+		result->binary.data = (JsonbContainer *) (base_addr + INTALIGN(offset));
+		result->binary.len = getJsonbLength(container, index) -
 			(INTALIGN(offset) - offset);
 	}
 }
@@ -576,10 +576,10 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
 	if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvObject)
 	{
 		pushJsonbValue(pstate, WJB_BEGIN_OBJECT, NULL);
-		for (i = 0; i < jbval->val.object.nPairs; i++)
+		for (i = 0; i < jbval->object.nPairs; i++)
 		{
-			pushJsonbValue(pstate, WJB_KEY, &jbval->val.object.pairs[i].key);
-			pushJsonbValue(pstate, WJB_VALUE, &jbval->val.object.pairs[i].value);
+			pushJsonbValue(pstate, WJB_KEY, &jbval->object.pairs[i].key);
+			pushJsonbValue(pstate, WJB_VALUE, &jbval->object.pairs[i].value);
 		}
 
 		return pushJsonbValue(pstate, WJB_END_OBJECT, NULL);
@@ -588,9 +588,9 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
 	if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvArray)
 	{
 		pushJsonbValue(pstate, WJB_BEGIN_ARRAY, NULL);
-		for (i = 0; i < jbval->val.array.nElems; i++)
+		for (i = 0; i < jbval->array.nElems; i++)
 		{
-			pushJsonbValue(pstate, WJB_ELEM, &jbval->val.array.elems[i]);
+			pushJsonbValue(pstate, WJB_ELEM, &jbval->array.elems[i]);
 		}
 
 		return pushJsonbValue(pstate, WJB_END_ARRAY, NULL);
@@ -604,13 +604,13 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
 	}
 
 	/* unpack the binary and add each piece to the pstate */
-	it = JsonbIteratorInit(jbval->val.binary.data);
+	it = JsonbIteratorInit(jbval->binary.data);
 
-	if ((jbval->val.binary.data->header & JB_FSCALAR) && *pstate)
+	if ((jbval->binary.data->header & JB_FSCALAR) && *pstate)
 	{
 		tok = JsonbIteratorNext(&it, &v, true);
 		Assert(tok == WJB_BEGIN_ARRAY);
-		Assert(v.type == jbvArray && v.val.array.rawScalar);
+		Assert(v.type == jbvArray && v.array.rawScalar);
 
 		tok = JsonbIteratorNext(&it, &v, true);
 		Assert(tok == WJB_ELEM);
@@ -628,7 +628,7 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
 		res = pushJsonbValueScalar(pstate, tok,
 								   tok < WJB_BEGIN_ARRAY ||
 								   (tok == WJB_BEGIN_ARRAY &&
-									v.val.array.rawScalar) ? &v : NULL);
+									v.array.rawScalar) ? &v : NULL);
 
 	return res;
 }
@@ -646,35 +646,35 @@ pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq,
 	switch (seq)
 	{
 		case WJB_BEGIN_ARRAY:
-			Assert(!scalarVal || scalarVal->val.array.rawScalar);
+			Assert(!scalarVal || scalarVal->array.rawScalar);
 			*pstate = pushState(pstate);
 			result = &(*pstate)->contVal;
 			(*pstate)->contVal.type = jbvArray;
-			(*pstate)->contVal.val.array.nElems = 0;
-			(*pstate)->contVal.val.array.rawScalar = (scalarVal &&
-													  scalarVal->val.array.rawScalar);
-			if (scalarVal && scalarVal->val.array.nElems > 0)
+			(*pstate)->contVal.array.nElems = 0;
+			(*pstate)->contVal.array.rawScalar = (scalarVal &&
+												  scalarVal->array.rawScalar);
+			if (scalarVal && scalarVal->array.nElems > 0)
 			{
 				/* Assume that this array is still really a scalar */
 				Assert(scalarVal->type == jbvArray);
-				(*pstate)->size = scalarVal->val.array.nElems;
+				(*pstate)->size = scalarVal->array.nElems;
 			}
 			else
 			{
 				(*pstate)->size = 4;
 			}
-			(*pstate)->contVal.val.array.elems = palloc(sizeof(JsonbValue) *
-														(*pstate)->size);
+			(*pstate)->contVal.array.elems = palloc(sizeof(JsonbValue) *
+													(*pstate)->size);
 			break;
 		case WJB_BEGIN_OBJECT:
 			Assert(!scalarVal);
 			*pstate = pushState(pstate);
 			result = &(*pstate)->contVal;
 			(*pstate)->contVal.type = jbvObject;
-			(*pstate)->contVal.val.object.nPairs = 0;
+			(*pstate)->contVal.object.nPairs = 0;
 			(*pstate)->size = 4;
-			(*pstate)->contVal.val.object.pairs = palloc(sizeof(JsonbPair) *
-														 (*pstate)->size);
+			(*pstate)->contVal.object.pairs = palloc(sizeof(JsonbPair) *
+													 (*pstate)->size);
 			break;
 		case WJB_KEY:
 			Assert(scalarVal->type == jbvString);
@@ -751,21 +751,21 @@ appendKey(JsonbParseState *pstate, JsonbValue *string)
 	Assert(object->type == jbvObject);
 	Assert(string->type == jbvString);
 
-	if (object->val.object.nPairs >= JSONB_MAX_PAIRS)
+	if (object->object.nPairs >= JSONB_MAX_PAIRS)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
 				 errmsg("number of jsonb object pairs exceeds the maximum allowed (%zu)",
 						JSONB_MAX_PAIRS)));
 
-	if (object->val.object.nPairs >= pstate->size)
+	if (object->object.nPairs >= pstate->size)
 	{
 		pstate->size *= 2;
-		object->val.object.pairs = repalloc(object->val.object.pairs,
-											sizeof(JsonbPair) * pstate->size);
+		object->object.pairs = repalloc(object->object.pairs,
+										sizeof(JsonbPair) * pstate->size);
 	}
 
-	object->val.object.pairs[object->val.object.nPairs].key = *string;
-	object->val.object.pairs[object->val.object.nPairs].order = object->val.object.nPairs;
+	object->object.pairs[object->object.nPairs].key = *string;
+	object->object.pairs[object->object.nPairs].order = object->object.nPairs;
 }
 
 /*
@@ -779,7 +779,7 @@ appendValue(JsonbParseState *pstate, JsonbValue *scalarVal)
 
 	Assert(object->type == jbvObject);
 
-	object->val.object.pairs[object->val.object.nPairs++].value = *scalarVal;
+	object->object.pairs[object->object.nPairs++].value = *scalarVal;
 }
 
 /*
@@ -792,20 +792,20 @@ appendElement(JsonbParseState *pstate, JsonbValue *scalarVal)
 
 	Assert(array->type == jbvArray);
 
-	if (array->val.array.nElems >= JSONB_MAX_ELEMS)
+	if (array->array.nElems >= JSONB_MAX_ELEMS)
 		ereport(ERROR,
 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
 				 errmsg("number of jsonb array elements exceeds the maximum allowed (%zu)",
 						JSONB_MAX_ELEMS)));
 
-	if (array->val.array.nElems >= pstate->size)
+	if (array->array.nElems >= pstate->size)
 	{
 		pstate->size *= 2;
-		array->val.array.elems = repalloc(array->val.array.elems,
-										  sizeof(JsonbValue) * pstate->size);
+		array->array.elems = repalloc(array->array.elems,
+									  sizeof(JsonbValue) * pstate->size);
 	}
 
-	array->val.array.elems[array->val.array.nElems++] = *scalarVal;
+	array->array.elems[array->array.nElems++] = *scalarVal;
 }
 
 /*
@@ -873,13 +873,13 @@ JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
 		case JBI_ARRAY_START:
 			/* Set v to array on first array call */
 			val->type = jbvArray;
-			val->val.array.nElems = (*it)->nElems;
+			val->array.nElems = (*it)->nElems;
 
 			/*
-			 * v->val.array.elems is not actually set, because we aren't doing
-			 * a full conversion
+			 * v->array.elems is not actually set, because we aren't doing a
+			 * full conversion
 			 */
-			val->val.array.rawScalar = (*it)->isScalar;
+			val->array.rawScalar = (*it)->isScalar;
 			(*it)->curIndex = 0;
 			(*it)->curDataOffset = 0;
 			(*it)->curValueOffset = 0;	/* not actually used */
@@ -912,7 +912,7 @@ JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
 			if (!IsAJsonbScalar(val) && !skipNested)
 			{
 				/* Recurse into container. */
-				*it = iteratorFromContainer(val->val.binary.data, *it);
+				*it = iteratorFromContainer(val->binary.data, *it);
 				goto recurse;
 			}
 			else
@@ -927,11 +927,11 @@ JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
 		case JBI_OBJECT_START:
 			/* Set v to object on first object call */
 			val->type = jbvObject;
-			val->val.object.nPairs = (*it)->nElems;
+			val->object.nPairs = (*it)->nElems;
 
 			/*
-			 * v->val.object.pairs is not actually set, because we aren't
-			 * doing a full conversion
+			 * v->object.pairs is not actually set, because we aren't doing a
+			 * full conversion
 			 */
 			(*it)->curIndex = 0;
 			(*it)->curDataOffset = 0;
@@ -989,7 +989,7 @@ JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
 			 */
 			if (!IsAJsonbScalar(val) && !skipNested)
 			{
-				*it = iteratorFromContainer(val->val.binary.data, *it);
+				*it = iteratorFromContainer(val->binary.data, *it);
 				goto recurse;
 			}
 			else
@@ -1111,7 +1111,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
 		 * optimization in the array case.)  The case probably won't arise
 		 * often, but since it's such a cheap check we may as well make it.
 		 */
-		if (vval.val.object.nPairs < vcontained.val.object.nPairs)
+		if (vval.object.nPairs < vcontained.object.nPairs)
 			return false;
 
 		/* Work through rhs "is it contained within?" object */
@@ -1136,8 +1136,8 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
 			/* First, find value by key... */
 			lhsVal =
 				getKeyJsonValueFromContainer((*val)->container,
-											 vcontained.val.string.val,
-											 vcontained.val.string.len,
+											 vcontained.string.val,
+											 vcontained.string.len,
 											 &lhsValBuf);
 			if (!lhsVal)
 				return false;
@@ -1172,8 +1172,8 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
 				Assert(lhsVal->type == jbvBinary);
 				Assert(vcontained.type == jbvBinary);
 
-				nestval = JsonbIteratorInit(lhsVal->val.binary.data);
-				nestContained = JsonbIteratorInit(vcontained.val.binary.data);
+				nestval = JsonbIteratorInit(lhsVal->binary.data);
+				nestContained = JsonbIteratorInit(vcontained.binary.data);
 
 				/*
 				 * Match "value" side of rhs datum object's pair recursively.
@@ -1203,7 +1203,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
 	else if (rcont == WJB_BEGIN_ARRAY)
 	{
 		JsonbValue *lhsConts = NULL;
-		uint32		nLhsElems = vval.val.array.nElems;
+		uint32		nLhsElems = vval.array.nElems;
 
 		Assert(vval.type == jbvArray);
 		Assert(vcontained.type == jbvArray);
@@ -1218,7 +1218,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
 		 * only contain pairs, never raw scalars (a pair is represented by an
 		 * rhs object argument with a single contained pair).
 		 */
-		if (vval.val.array.rawScalar && !vcontained.val.array.rawScalar)
+		if (vval.array.rawScalar && !vcontained.array.rawScalar)
 			return false;
 
 		/* Work through rhs "is it contained within?" array */
@@ -1284,8 +1284,8 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
 							   *nestContained;
 					bool		contains;
 
-					nestval = JsonbIteratorInit(lhsConts[i].val.binary.data);
-					nestContained = JsonbIteratorInit(vcontained.val.binary.data);
+					nestval = JsonbIteratorInit(lhsConts[i].binary.data);
+					nestContained = JsonbIteratorInit(vcontained.binary.data);
 
 					contains = JsonbDeepContains(&nestval, &nestContained);
 
@@ -1334,16 +1334,16 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
 			tmp = 0x01;
 			break;
 		case jbvString:
-			tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->val.string.val,
-										  scalarVal->val.string.len));
+			tmp = DatumGetUInt32(hash_any((const unsigned char *) scalarVal->string.val,
+										  scalarVal->string.len));
 			break;
 		case jbvNumeric:
 			/* Must hash equal numerics to equal hash codes */
 			tmp = DatumGetUInt32(DirectFunctionCall1(hash_numeric,
-													 NumericGetDatum(scalarVal->val.numeric)));
+													 NumericGetDatum(scalarVal->numeric)));
 			break;
 		case jbvBool:
-			tmp = scalarVal->val.boolean ? 0x02 : 0x04;
+			tmp = scalarVal->boolean ? 0x02 : 0x04;
 
 			break;
 		default:
@@ -1377,22 +1377,22 @@ JsonbHashScalarValueExtended(const JsonbValue *scalarVal, uint64 *hash,
 			tmp = seed + 0x01;
 			break;
 		case jbvString:
-			tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->val.string.val,
-												   scalarVal->val.string.len,
+			tmp = DatumGetUInt64(hash_any_extended((const unsigned char *) scalarVal->string.val,
+												   scalarVal->string.len,
 												   seed));
 			break;
 		case jbvNumeric:
 			tmp = DatumGetUInt64(DirectFunctionCall2(hash_numeric_extended,
-													 NumericGetDatum(scalarVal->val.numeric),
+													 NumericGetDatum(scalarVal->numeric),
 													 UInt64GetDatum(seed)));
 			break;
 		case jbvBool:
 			if (seed)
 				tmp = DatumGetUInt64(DirectFunctionCall2(hashcharextended,
-														 BoolGetDatum(scalarVal->val.boolean),
+														 BoolGetDatum(scalarVal->boolean),
 														 UInt64GetDatum(seed)));
 			else
-				tmp = scalarVal->val.boolean ? 0x02 : 0x04;
+				tmp = scalarVal->boolean ? 0x02 : 0x04;
 
 			break;
 		default:
@@ -1420,10 +1420,10 @@ equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b)
 				return lengthCompareJsonbStringValue(a, b) == 0;
 			case jbvNumeric:
 				return DatumGetBool(DirectFunctionCall2(numeric_eq,
-														PointerGetDatum(a->val.numeric),
-														PointerGetDatum(b->val.numeric)));
+														PointerGetDatum(a->numeric),
+														PointerGetDatum(b->numeric)));
 			case jbvBool:
-				return a->val.boolean == b->val.boolean;
+				return a->boolean == b->boolean;
 
 			default:
 				elog(ERROR, "invalid jsonb scalar type");
@@ -1449,19 +1449,19 @@ compareJsonbScalarValue(JsonbValue *a, JsonbValue *b)
 			case jbvNull:
 				return 0;
 			case jbvString:
-				return varstr_cmp(a->val.string.val,
-								  a->val.string.len,
-								  b->val.string.val,
-								  b->val.string.len,
+				return varstr_cmp(a->string.val,
+								  a->string.len,
+								  b->string.val,
+								  b->string.len,
 								  DEFAULT_COLLATION_OID);
 			case jbvNumeric:
 				return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
-														 PointerGetDatum(a->val.numeric),
-														 PointerGetDatum(b->val.numeric)));
+														 PointerGetDatum(a->numeric),
+														 PointerGetDatum(b->numeric)));
 			case jbvBool:
-				if (a->val.boolean == b->val.boolean)
+				if (a->boolean == b->boolean)
 					return 0;
-				else if (a->val.boolean > b->val.boolean)
+				else if (a->boolean > b->boolean)
 					return 1;
 				else
 					return -1;
@@ -1629,7 +1629,7 @@ convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
 	int			i;
 	int			totallen;
 	uint32		containerhead;
-	int			nElems = val->val.array.nElems;
+	int			nElems = val->array.nElems;
 
 	/* Remember where in the buffer this array starts. */
 	base_offset = buffer->len;
@@ -1642,7 +1642,7 @@ convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
 	 * variable-length payload.
 	 */
 	containerhead = nElems | JB_FARRAY;
-	if (val->val.array.rawScalar)
+	if (val->array.rawScalar)
 	{
 		Assert(nElems == 1);
 		Assert(level == 0);
@@ -1657,7 +1657,7 @@ convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level)
 	totallen = 0;
 	for (i = 0; i < nElems; i++)
 	{
-		JsonbValue *elem = &val->val.array.elems[i];
+		JsonbValue *elem = &val->array.elems[i];
 		int			len;
 		JEntry		meta;
 
@@ -1713,7 +1713,7 @@ convertJsonbObject(StringInfo buffer, JEntry *header, JsonbValue *val, int level
 	int			i;
 	int			totallen;
 	uint32		containerheader;
-	int			nPairs = val->val.object.nPairs;
+	int			nPairs = val->object.nPairs;
 
 	/* Remember where in the buffer this object starts. */
 	base_offset = buffer->len;
@@ -1738,7 +1738,7 @@ convertJsonbObject(StringInfo buffer, JEntry *header, JsonbValue *val, int level
 	totallen = 0;
 	for (i = 0; i < nPairs; i++)
 	{
-		JsonbPair  *pair = &val->val.object.pairs[i];
+		JsonbPair  *pair = &val->object.pairs[i];
 		int			len;
 		JEntry		meta;
 
@@ -1773,7 +1773,7 @@ convertJsonbObject(StringInfo buffer, JEntry *header, JsonbValue *val, int level
 	}
 	for (i = 0; i < nPairs; i++)
 	{
-		JsonbPair  *pair = &val->val.object.pairs[i];
+		JsonbPair  *pair = &val->object.pairs[i];
 		int			len;
 		JEntry		meta;
 
@@ -1834,22 +1834,22 @@ convertJsonbScalar(StringInfo buffer, JEntry *header, JsonbValue *scalarVal)
 			break;
 
 		case jbvString:
-			appendToBuffer(buffer, scalarVal->val.string.val, scalarVal->val.string.len);
+			appendToBuffer(buffer, scalarVal->string.val, scalarVal->string.len);
 
-			*header = scalarVal->val.string.len;
+			*header = scalarVal->string.len;
 			break;
 
 		case jbvNumeric:
-			numlen = VARSIZE_ANY(scalarVal->val.numeric);
+			numlen = VARSIZE_ANY(scalarVal->numeric);
 			padlen = padBufferToInt(buffer);
 
-			appendToBuffer(buffer, scalarVal->val.numeric, numlen);
+			appendToBuffer(buffer, scalarVal->numeric, numlen);
 
 			*header = JENTRY_ISNUMERIC | (padlen + numlen);
 			break;
 
 		case jbvBool:
-			*header = (scalarVal->val.boolean) ?
+			*header = (scalarVal->boolean) ?
 				JENTRY_ISBOOL_TRUE : JENTRY_ISBOOL_FALSE;
 			break;
 
@@ -1859,9 +1859,9 @@ convertJsonbScalar(StringInfo buffer, JEntry *header, JsonbValue *scalarVal)
 				size_t		len;
 
 				JsonEncodeDateTime(buf,
-								   scalarVal->val.datetime.value,
-								   scalarVal->val.datetime.typid,
-								   &scalarVal->val.datetime.tz);
+								   scalarVal->datetime.value,
+								   scalarVal->datetime.typid,
+								   &scalarVal->datetime.tz);
 				len = strlen(buf);
 				appendToBuffer(buffer, buf, len);
 
@@ -1895,8 +1895,8 @@ lengthCompareJsonbStringValue(const void *a, const void *b)
 	Assert(va->type == jbvString);
 	Assert(vb->type == jbvString);
 
-	return lengthCompareJsonbString(va->val.string.val, va->val.string.len,
-									vb->val.string.val, vb->val.string.len);
+	return lengthCompareJsonbString(va->string.val, va->string.len,
+									vb->string.val, vb->string.len);
 }
 
 /*
@@ -1956,8 +1956,8 @@ uniqueifyJsonbObject(JsonbValue *object, bool unique_keys, bool skip_nulls)
 
 	Assert(object->type == jbvObject);
 
-	if (object->val.object.nPairs > 1)
-		qsort_arg(object->val.object.pairs, object->val.object.nPairs, sizeof(JsonbPair),
+	if (object->object.nPairs > 1)
+		qsort_arg(object->object.pairs, object->object.nPairs, sizeof(JsonbPair),
 				  lengthCompareJsonbPair, &hasNonUniq);
 
 	if (hasNonUniq && unique_keys)
@@ -1970,20 +1970,20 @@ uniqueifyJsonbObject(JsonbValue *object, bool unique_keys, bool skip_nulls)
 		JsonbPair  *ptr,
 				   *res;
 
-		while (skip_nulls && object->val.object.nPairs > 0 &&
-			   object->val.object.pairs->value.type == jbvNull)
+		while (skip_nulls && object->object.nPairs > 0 &&
+			   object->object.pairs->value.type == jbvNull)
 		{
 			/* If skip_nulls is true, remove leading items with null */
-			object->val.object.pairs++;
-			object->val.object.nPairs--;
+			object->object.pairs++;
+			object->object.nPairs--;
 		}
 
-		if (object->val.object.nPairs > 0)
+		if (object->object.nPairs > 0)
 		{
-			ptr = object->val.object.pairs + 1;
-			res = object->val.object.pairs;
+			ptr = object->object.pairs + 1;
+			res = object->object.pairs;
 
-			while (ptr - object->val.object.pairs < object->val.object.nPairs)
+			while (ptr - object->object.pairs < object->object.nPairs)
 			{
 				/* Avoid copying over duplicate or null */
 				if (lengthCompareJsonbStringValue(ptr, res) != 0 &&
@@ -1996,7 +1996,7 @@ uniqueifyJsonbObject(JsonbValue *object, bool unique_keys, bool skip_nulls)
 				ptr++;
 			}
 
-			object->val.object.nPairs = res + 1 - object->val.object.pairs;
+			object->object.nPairs = res + 1 - object->object.pairs;
 		}
 	}
 }
diff --git a/src/backend/utils/adt/jsonbsubs.c b/src/backend/utils/adt/jsonbsubs.c
index 8211de23d59..8231cde7dbe 100644
--- a/src/backend/utils/adt/jsonbsubs.c
+++ b/src/backend/utils/adt/jsonbsubs.c
@@ -289,13 +289,13 @@ jsonb_subscript_assign(ExprState *state,
 		if (workspace->expectArray)
 		{
 			newSource.type = jbvArray;
-			newSource.val.array.nElems = 0;
-			newSource.val.array.rawScalar = false;
+			newSource.array.nElems = 0;
+			newSource.array.rawScalar = false;
 		}
 		else
 		{
 			newSource.type = jbvObject;
-			newSource.val.object.nPairs = 0;
+			newSource.object.nPairs = 0;
 		}
 
 		jsonbSource = JsonbValueToJsonb(&newSource);
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index c5e1a027956..adfdd487bcf 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -175,7 +175,7 @@ typedef struct CompositeIOData
 {
 	/*
 	 * We use pointer to a RecordIOData here because variable-length struct
-	 * RecordIOData can't be used directly in ColumnIOData.io union
+	 * RecordIOData can't be used directly in ColumnIOData union
 	 */
 	RecordIOData *record_io;	/* metadata cache for populate_record() */
 	TupleDesc	tupdesc;		/* cached tuple descriptor */
@@ -220,7 +220,7 @@ struct ColumnIOData
 		ArrayIOData array;
 		CompositeIOData composite;
 		DomainIOData domain;
-	}			io;				/* metadata cache for various column type
+	};							/* metadata cache for various column type
 								 * categories */
 };
 
@@ -303,7 +303,7 @@ typedef struct JsValue
 		}			json;		/* json value */
 
 		JsonbValue *jsonb;		/* jsonb value */
-	}			val;
+	};
 } JsValue;
 
 typedef struct JsObject
@@ -313,29 +313,29 @@ typedef struct JsObject
 	{
 		HTAB	   *json_hash;
 		JsonbContainer *jsonb_cont;
-	}			val;
+	};
 } JsObject;
 
 /* useful macros for testing JsValue properties */
 #define JsValueIsNull(jsv) \
 	((jsv)->is_json ?  \
-		(!(jsv)->val.json.str || (jsv)->val.json.type == JSON_TOKEN_NULL) : \
-		(!(jsv)->val.jsonb || (jsv)->val.jsonb->type == jbvNull))
+		(!(jsv)->json.str || (jsv)->json.type == JSON_TOKEN_NULL) : \
+		(!(jsv)->jsonb || (jsv)->jsonb->type == jbvNull))
 
 #define JsValueIsString(jsv) \
-	((jsv)->is_json ? (jsv)->val.json.type == JSON_TOKEN_STRING \
-		: ((jsv)->val.jsonb && (jsv)->val.jsonb->type == jbvString))
+	((jsv)->is_json ? (jsv)->json.type == JSON_TOKEN_STRING \
+		: ((jsv)->jsonb && (jsv)->jsonb->type == jbvString))
 
 #define JsObjectIsEmpty(jso) \
 	((jso)->is_json \
-		? hash_get_num_entries((jso)->val.json_hash) == 0 \
-		: ((jso)->val.jsonb_cont == NULL || \
-		   JsonContainerSize((jso)->val.jsonb_cont) == 0))
+		? hash_get_num_entries((jso)->json_hash) == 0 \
+		: ((jso)->jsonb_cont == NULL || \
+		   JsonContainerSize((jso)->jsonb_cont) == 0))
 
 #define JsObjectFree(jso) \
 	do { \
 		if ((jso)->is_json) \
-			hash_destroy((jso)->val.json_hash); \
+			hash_destroy((jso)->json_hash); \
 	} while (0)
 
 static int	report_json_context(JsonLexContext *lex);
@@ -610,9 +610,9 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
 			{
 				char	   *cstr;
 
-				cstr = palloc(v.val.string.len + 1 * sizeof(char));
-				memcpy(cstr, v.val.string.val, v.val.string.len);
-				cstr[v.val.string.len] = '\0';
+				cstr = palloc(v.string.len + 1 * sizeof(char));
+				memcpy(cstr, v.string.val, v.string.len);
+				cstr[v.string.len] = '\0';
 				state->result[state->result_count++] = cstr;
 			}
 		}
@@ -1643,7 +1643,7 @@ jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
 
 		if (jbvp->type == jbvBinary)
 		{
-			container = jbvp->val.binary.data;
+			container = jbvp->binary.data;
 			have_object = JsonContainerIsObject(container);
 			have_array = JsonContainerIsArray(container);
 			Assert(!JsonContainerIsScalar(container));
@@ -1684,8 +1684,8 @@ jsonb_set_element(Jsonb *jb, Datum *path, int path_len,
 	JsonbIterator *it;
 	bool	   *path_nulls = palloc0(path_len * sizeof(bool));
 
-	if (newval->type == jbvArray && newval->val.array.rawScalar)
-		*newval = newval->val.array.elems[0];
+	if (newval->type == jbvArray && newval->array.rawScalar)
+		*newval = newval->array.elems[0];
 
 	it = JsonbIteratorInit(&jb->root);
 
@@ -1755,8 +1755,8 @@ push_path(JsonbParseState **st, int level, Datum *path_elems,
 		{
 			/* text, an object is expected */
 			newkey.type = jbvString;
-			newkey.val.string.val = c;
-			newkey.val.string.len = strlen(c);
+			newkey.string.val = c;
+			newkey.string.len = strlen(c);
 
 			(void) pushJsonbValue(st, WJB_BEGIN_OBJECT, NULL);
 			(void) pushJsonbValue(st, WJB_KEY, &newkey);
@@ -1810,20 +1810,20 @@ JsonbValueAsText(JsonbValue *v)
 			return NULL;
 
 		case jbvBool:
-			return v->val.boolean ?
+			return v->boolean ?
 				cstring_to_text_with_len("true", 4) :
 				cstring_to_text_with_len("false", 5);
 
 		case jbvString:
-			return cstring_to_text_with_len(v->val.string.val,
-											v->val.string.len);
+			return cstring_to_text_with_len(v->string.val,
+											v->string.len);
 
 		case jbvNumeric:
 			{
 				Datum		cstr;
 
 				cstr = DirectFunctionCall1(numeric_out,
-										   PointerGetDatum(v->val.numeric));
+										   PointerGetDatum(v->numeric));
 
 				return cstring_to_text(DatumGetCString(cstr));
 			}
@@ -1833,8 +1833,8 @@ JsonbValueAsText(JsonbValue *v)
 				StringInfoData jtext;
 
 				initStringInfo(&jtext);
-				(void) JsonbToCString(&jtext, v->val.binary.data,
-									  v->val.binary.len);
+				(void) JsonbToCString(&jtext, v->binary.data,
+									  v->binary.len);
 
 				return cstring_to_text_with_len(jtext.data, jtext.len);
 			}
@@ -2010,7 +2010,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
 			/* Use the tmp context so we can clean up after each tuple is done */
 			old_cxt = MemoryContextSwitchTo(tmp_cxt);
 
-			key = cstring_to_text_with_len(v.val.string.val, v.val.string.len);
+			key = cstring_to_text_with_len(v.string.val, v.string.len);
 
 			/*
 			 * The next thing the iterator fetches should be the value, no
@@ -2720,24 +2720,24 @@ populate_array_element_end(void *_state, bool isnull)
 		JsValue		jsv;
 
 		jsv.is_json = true;
-		jsv.val.json.type = state->element_type;
+		jsv.json.type = state->element_type;
 
 		if (isnull)
 		{
-			Assert(jsv.val.json.type == JSON_TOKEN_NULL);
-			jsv.val.json.str = NULL;
-			jsv.val.json.len = 0;
+			Assert(jsv.json.type == JSON_TOKEN_NULL);
+			jsv.json.str = NULL;
+			jsv.json.len = 0;
 		}
 		else if (state->element_scalar)
 		{
-			jsv.val.json.str = state->element_scalar;
-			jsv.val.json.len = -1;	/* null-terminated */
+			jsv.json.str = state->element_scalar;
+			jsv.json.len = -1;	/* null-terminated */
 		}
 		else
 		{
-			jsv.val.json.str = state->element_start;
-			jsv.val.json.len = (state->lex->prev_token_terminator -
-								state->element_start) * sizeof(char);
+			jsv.json.str = state->element_start;
+			jsv.json.len = (state->lex->prev_token_terminator -
+							state->element_start) * sizeof(char);
 		}
 
 		/* Report if an error occurred. */
@@ -2826,7 +2826,7 @@ populate_array_dim_jsonb(PopulateArrayContext *ctx, /* context */
 						 JsonbValue *jbv,	/* jsonb sub-array */
 						 int ndim)	/* current dimension */
 {
-	JsonbContainer *jbc = jbv->val.binary.data;
+	JsonbContainer *jbc = jbv->binary.data;
 	JsonbIterator *it;
 	JsonbIteratorToken tok;
 	JsonbValue	val;
@@ -2860,14 +2860,14 @@ populate_array_dim_jsonb(PopulateArrayContext *ctx, /* context */
 		(tok == WJB_END_ARRAY ||
 		 (tok == WJB_ELEM &&
 		  (val.type != jbvBinary ||
-		   !JsonContainerIsArray(val.val.binary.data)))))
+		   !JsonContainerIsArray(val.binary.data)))))
 	{
 		if (!populate_array_assign_ndims(ctx, ndim))
 			return false;
 	}
 
 	jsv.is_json = false;
-	jsv.val.jsonb = &val;
+	jsv.jsonb = &val;
 
 	/* process all the array elements */
 	while (tok == WJB_ELEM)
@@ -2937,9 +2937,9 @@ populate_array(ArrayIOData *aio,
 	if (jsv->is_json)
 	{
 		/* Return null if an error was found. */
-		if (!populate_array_json(&ctx, jsv->val.json.str,
-								 jsv->val.json.len >= 0 ? jsv->val.json.len
-								 : strlen(jsv->val.json.str)))
+		if (!populate_array_json(&ctx, jsv->json.str,
+								 jsv->json.len >= 0 ? jsv->json.len
+								 : strlen(jsv->json.str)))
 		{
 			*isnull = true;
 			return (Datum) 0;
@@ -2948,7 +2948,7 @@ populate_array(ArrayIOData *aio,
 	else
 	{
 		/* Return null if an error was found. */
-		if (!populate_array_dim_jsonb(&ctx, jsv->val.jsonb, 1))
+		if (!populate_array_dim_jsonb(&ctx, jsv->jsonb, 1))
 		{
 			*isnull = true;
 			return (Datum) 0;
@@ -2986,23 +2986,23 @@ JsValueToJsObject(JsValue *jsv, JsObject *jso, Node *escontext)
 	if (jsv->is_json)
 	{
 		/* convert plain-text json into a hash table */
-		jso->val.json_hash =
-			get_json_object_as_hash(jsv->val.json.str,
-									jsv->val.json.len >= 0
-									? jsv->val.json.len
-									: strlen(jsv->val.json.str),
+		jso->json_hash =
+			get_json_object_as_hash(jsv->json.str,
+									jsv->json.len >= 0
+									? jsv->json.len
+									: strlen(jsv->json.str),
 									"populate_composite",
 									escontext);
-		Assert(jso->val.json_hash != NULL || SOFT_ERROR_OCCURRED(escontext));
+		Assert(jso->json_hash != NULL || SOFT_ERROR_OCCURRED(escontext));
 	}
 	else
 	{
-		JsonbValue *jbv = jsv->val.jsonb;
+		JsonbValue *jbv = jsv->jsonb;
 
 		if (jbv->type == jbvBinary &&
-			JsonContainerIsObject(jbv->val.binary.data))
+			JsonContainerIsObject(jbv->binary.data))
 		{
-			jso->val.jsonb_cont = jbv->val.binary.data;
+			jso->jsonb_cont = jbv->binary.data;
 		}
 		else
 		{
@@ -3010,7 +3010,7 @@ JsValueToJsObject(JsValue *jsv, JsObject *jso, Node *escontext)
 
 			is_scalar = IsAJsonbScalar(jbv) ||
 				(jbv->type == jbvBinary &&
-				 JsonContainerIsScalar(jbv->val.binary.data));
+				 JsonContainerIsScalar(jbv->binary.data));
 			errsave(escontext,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 is_scalar
@@ -3131,14 +3131,14 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv,
 
 	if (jsv->is_json)
 	{
-		int			len = jsv->val.json.len;
+		int			len = jsv->json.len;
 
-		json = jsv->val.json.str;
+		json = jsv->json.str;
 		Assert(json);
 
 		/* If converting to json/jsonb, make string into valid JSON literal */
 		if ((typid == JSONOID || typid == JSONBOID) &&
-			jsv->val.json.type == JSON_TOKEN_STRING)
+			jsv->json.type == JSON_TOKEN_STRING)
 		{
 			StringInfoData buf;
 
@@ -3164,10 +3164,10 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv,
 	}
 	else
 	{
-		JsonbValue *jbv = jsv->val.jsonb;
+		JsonbValue *jbv = jsv->jsonb;
 
 		if (jbv->type == jbvString && omit_quotes)
-			str = pnstrdup(jbv->val.string.val, jbv->val.string.len);
+			str = pnstrdup(jbv->string.val, jbv->string.len);
 		else if (typid == JSONBOID)
 		{
 			Jsonb	   *jsonb = JsonbValueToJsonb(jbv); /* directly use jsonb */
@@ -3186,15 +3186,15 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv,
 			str = JsonbToCString(NULL, &jsonb->root, VARSIZE(jsonb));
 		}
 		else if (jbv->type == jbvString)	/* quotes are stripped */
-			str = pnstrdup(jbv->val.string.val, jbv->val.string.len);
+			str = pnstrdup(jbv->string.val, jbv->string.len);
 		else if (jbv->type == jbvBool)
-			str = pstrdup(jbv->val.boolean ? "true" : "false");
+			str = pstrdup(jbv->boolean ? "true" : "false");
 		else if (jbv->type == jbvNumeric)
 			str = DatumGetCString(DirectFunctionCall1(numeric_out,
-													  PointerGetDatum(jbv->val.numeric)));
+													  PointerGetDatum(jbv->numeric)));
 		else if (jbv->type == jbvBinary)
-			str = JsonbToCString(NULL, jbv->val.binary.data,
-								 jbv->val.binary.len);
+			str = JsonbToCString(NULL, jbv->binary.data,
+								 jbv->binary.len);
 		else
 			elog(ERROR, "unrecognized jsonb type: %d", (int) jbv->type);
 	}
@@ -3280,40 +3280,40 @@ prepare_column_cache(ColumnIOData *column,
 		{
 			/* domain over composite has its own code path */
 			column->typcat = TYPECAT_COMPOSITE_DOMAIN;
-			column->io.composite.record_io = NULL;
-			column->io.composite.tupdesc = NULL;
-			column->io.composite.base_typid = base_typid;
-			column->io.composite.base_typmod = base_typmod;
-			column->io.composite.domain_info = NULL;
+			column->composite.record_io = NULL;
+			column->composite.tupdesc = NULL;
+			column->composite.base_typid = base_typid;
+			column->composite.base_typmod = base_typmod;
+			column->composite.domain_info = NULL;
 		}
 		else
 		{
 			/* domain over anything else */
 			column->typcat = TYPECAT_DOMAIN;
-			column->io.domain.base_typid = base_typid;
-			column->io.domain.base_typmod = base_typmod;
-			column->io.domain.base_io =
+			column->domain.base_typid = base_typid;
+			column->domain.base_typmod = base_typmod;
+			column->domain.base_io =
 				MemoryContextAllocZero(mcxt, sizeof(ColumnIOData));
-			column->io.domain.domain_info = NULL;
+			column->domain.domain_info = NULL;
 		}
 	}
 	else if (type->typtype == TYPTYPE_COMPOSITE || typid == RECORDOID)
 	{
 		column->typcat = TYPECAT_COMPOSITE;
-		column->io.composite.record_io = NULL;
-		column->io.composite.tupdesc = NULL;
-		column->io.composite.base_typid = typid;
-		column->io.composite.base_typmod = typmod;
-		column->io.composite.domain_info = NULL;
+		column->composite.record_io = NULL;
+		column->composite.tupdesc = NULL;
+		column->composite.base_typid = typid;
+		column->composite.base_typmod = typmod;
+		column->composite.domain_info = NULL;
 	}
 	else if (IsTrueArrayType(type))
 	{
 		column->typcat = TYPECAT_ARRAY;
-		column->io.array.element_info = MemoryContextAllocZero(mcxt,
-															   sizeof(ColumnIOData));
-		column->io.array.element_type = type->typelem;
+		column->array.element_info = MemoryContextAllocZero(mcxt,
+															sizeof(ColumnIOData));
+		column->array.element_type = type->typelem;
 		/* array element typemod stored in attribute's typmod */
-		column->io.array.element_typmod = typmod;
+		column->array.element_typmod = typmod;
 	}
 	else
 	{
@@ -3356,24 +3356,24 @@ json_populate_type(Datum json_val, Oid json_type,
 	if (*isnull)
 	{
 		if (jsv.is_json)
-			jsv.val.json.str = NULL;
+			jsv.json.str = NULL;
 		else
-			jsv.val.jsonb = NULL;
+			jsv.jsonb = NULL;
 	}
 	else if (jsv.is_json)
 	{
 		text	   *json = DatumGetTextPP(json_val);
 
-		jsv.val.json.str = VARDATA_ANY(json);
-		jsv.val.json.len = VARSIZE_ANY_EXHDR(json);
-		jsv.val.json.type = JSON_TOKEN_INVALID; /* not used in
-												 * populate_composite() */
+		jsv.json.str = VARDATA_ANY(json);
+		jsv.json.len = VARSIZE_ANY_EXHDR(json);
+		jsv.json.type = JSON_TOKEN_INVALID; /* not used in
+											 * populate_composite() */
 	}
 	else
 	{
 		Jsonb	   *jsonb = DatumGetJsonbP(json_val);
 
-		jsv.val.jsonb = &jbv;
+		jsv.jsonb = &jbv;
 
 		if (omit_quotes)
 		{
@@ -3381,15 +3381,15 @@ json_populate_type(Datum json_val, Oid json_type,
 
 			/* fill the quote-stripped string */
 			jbv.type = jbvString;
-			jbv.val.string.len = strlen(str);
-			jbv.val.string.val = str;
+			jbv.string.len = strlen(str);
+			jbv.string.val = str;
 		}
 		else
 		{
 			/* fill binary jsonb value pointing to jb */
 			jbv.type = jbvBinary;
-			jbv.val.binary.data = &jsonb->root;
-			jbv.val.binary.len = VARSIZE(jsonb) - VARHDRSZ;
+			jbv.binary.data = &jsonb->root;
+			jbv.binary.len = VARSIZE(jsonb) - VARHDRSZ;
 		}
 	}
 
@@ -3449,12 +3449,12 @@ populate_record_field(ColumnIOData *col,
 								   isnull, escontext, omit_scalar_quotes);
 
 		case TYPECAT_ARRAY:
-			return populate_array(&col->io.array, colname, mcxt, jsv,
+			return populate_array(&col->array, colname, mcxt, jsv,
 								  isnull, escontext);
 
 		case TYPECAT_COMPOSITE:
 		case TYPECAT_COMPOSITE_DOMAIN:
-			return populate_composite(&col->io.composite, typid,
+			return populate_composite(&col->composite, typid,
 									  colname, mcxt,
 									  DatumGetPointer(defaultval)
 									  ? DatumGetHeapTupleHeader(defaultval)
@@ -3463,7 +3463,7 @@ populate_record_field(ColumnIOData *col,
 									  escontext);
 
 		case TYPECAT_DOMAIN:
-			return populate_domain(&col->io.domain, typid, colname, mcxt,
+			return populate_domain(&col->domain, typid, colname, mcxt,
 								   jsv, isnull, escontext, omit_scalar_quotes);
 
 		default:
@@ -3495,23 +3495,23 @@ JsObjectGetField(JsObject *obj, char *field, JsValue *jsv)
 
 	if (jsv->is_json)
 	{
-		JsonHashEntry *hashentry = hash_search(obj->val.json_hash, field,
+		JsonHashEntry *hashentry = hash_search(obj->json_hash, field,
 											   HASH_FIND, NULL);
 
-		jsv->val.json.type = hashentry ? hashentry->type : JSON_TOKEN_NULL;
-		jsv->val.json.str = jsv->val.json.type == JSON_TOKEN_NULL ? NULL :
+		jsv->json.type = hashentry ? hashentry->type : JSON_TOKEN_NULL;
+		jsv->json.str = jsv->json.type == JSON_TOKEN_NULL ? NULL :
 			hashentry->val;
-		jsv->val.json.len = jsv->val.json.str ? -1 : 0; /* null-terminated */
+		jsv->json.len = jsv->json.str ? -1 : 0; /* null-terminated */
 
 		return hashentry != NULL;
 	}
 	else
 	{
-		jsv->val.jsonb = !obj->val.jsonb_cont ? NULL :
-			getKeyJsonValueFromContainer(obj->val.jsonb_cont, field, strlen(field),
+		jsv->jsonb = !obj->jsonb_cont ? NULL :
+			getKeyJsonValueFromContainer(obj->jsonb_cont, field, strlen(field),
 										 NULL);
 
-		return jsv->val.jsonb != NULL;
+		return jsv->jsonb != NULL;
 	}
 }
 
@@ -3680,14 +3680,14 @@ get_record_type_from_query(FunctionCallInfo fcinfo,
 	cache->argtype = tupdesc->tdtypeid;
 
 	/* If we go through this more than once, avoid memory leak */
-	if (cache->c.io.composite.tupdesc)
-		FreeTupleDesc(cache->c.io.composite.tupdesc);
+	if (cache->c.composite.tupdesc)
+		FreeTupleDesc(cache->c.composite.tupdesc);
 
 	/* Save identified tupdesc */
 	old_cxt = MemoryContextSwitchTo(cache->fn_mcxt);
-	cache->c.io.composite.tupdesc = CreateTupleDescCopy(tupdesc);
-	cache->c.io.composite.base_typid = tupdesc->tdtypeid;
-	cache->c.io.composite.base_typmod = tupdesc->tdtypmod;
+	cache->c.composite.tupdesc = CreateTupleDescCopy(tupdesc);
+	cache->c.composite.base_typid = tupdesc->tdtypeid;
+	cache->c.composite.base_typmod = tupdesc->tdtypmod;
 	MemoryContextSwitchTo(old_cxt);
 }
 
@@ -3739,8 +3739,8 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname,
 		 */
 		if (cache->argtype == RECORDOID)
 		{
-			cache->c.io.composite.base_typid = HeapTupleHeaderGetTypeId(rec);
-			cache->c.io.composite.base_typmod = HeapTupleHeaderGetTypMod(rec);
+			cache->c.composite.base_typid = HeapTupleHeaderGetTypeId(rec);
+			cache->c.composite.base_typmod = HeapTupleHeaderGetTypMod(rec);
 		}
 	}
 	else
@@ -3774,25 +3774,25 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname,
 	{
 		text	   *json = PG_GETARG_TEXT_PP(json_arg_num);
 
-		jsv.val.json.str = VARDATA_ANY(json);
-		jsv.val.json.len = VARSIZE_ANY_EXHDR(json);
-		jsv.val.json.type = JSON_TOKEN_INVALID; /* not used in
-												 * populate_composite() */
+		jsv.json.str = VARDATA_ANY(json);
+		jsv.json.len = VARSIZE_ANY_EXHDR(json);
+		jsv.json.type = JSON_TOKEN_INVALID; /* not used in
+											 * populate_composite() */
 	}
 	else
 	{
 		Jsonb	   *jb = PG_GETARG_JSONB_P(json_arg_num);
 
-		jsv.val.jsonb = &jbv;
+		jsv.jsonb = &jbv;
 
 		/* fill binary jsonb value pointing to jb */
 		jbv.type = jbvBinary;
-		jbv.val.binary.data = &jb->root;
-		jbv.val.binary.len = VARSIZE(jb) - VARHDRSZ;
+		jbv.binary.data = &jb->root;
+		jbv.binary.len = VARSIZE(jb) - VARHDRSZ;
 	}
 
 	isnull = false;
-	rettuple = populate_composite(&cache->c.io.composite, cache->argtype,
+	rettuple = populate_composite(&cache->c.composite, cache->argtype,
 								  NULL, fnmcxt, rec, &jsv, &isnull,
 								  escontext);
 	Assert(!isnull || SOFT_ERROR_OCCURRED(escontext));
@@ -4006,11 +4006,11 @@ populate_recordset_record(PopulateRecordsetState *state, JsObject *obj)
 	HeapTupleData tuple;
 
 	/* acquire/update cached tuple descriptor */
-	update_cached_tupdesc(&cache->c.io.composite, cache->fn_mcxt);
+	update_cached_tupdesc(&cache->c.composite, cache->fn_mcxt);
 
 	/* replace record fields from json */
-	tuphead = populate_record(cache->c.io.composite.tupdesc,
-							  &cache->c.io.composite.record_io,
+	tuphead = populate_record(cache->c.composite.tupdesc,
+							  &cache->c.composite.record_io,
 							  state->rec,
 							  cache->fn_mcxt,
 							  obj,
@@ -4020,7 +4020,7 @@ populate_recordset_record(PopulateRecordsetState *state, JsObject *obj)
 	if (cache->c.typcat == TYPECAT_COMPOSITE_DOMAIN)
 		(void) domain_check_safe(HeapTupleHeaderGetDatum(tuphead), false,
 								 cache->argtype,
-								 &cache->c.io.composite.domain_info,
+								 &cache->c.composite.domain_info,
 								 cache->fn_mcxt,
 								 NULL);
 
@@ -4092,8 +4092,8 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
 		 */
 		if (cache->argtype == RECORDOID)
 		{
-			cache->c.io.composite.base_typid = HeapTupleHeaderGetTypeId(rec);
-			cache->c.io.composite.base_typmod = HeapTupleHeaderGetTypMod(rec);
+			cache->c.composite.base_typid = HeapTupleHeaderGetTypeId(rec);
+			cache->c.composite.base_typmod = HeapTupleHeaderGetTypMod(rec);
 		}
 	}
 	else
@@ -4120,7 +4120,7 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
 	 * Forcibly update the cached tupdesc, to ensure we have the right tupdesc
 	 * to return even if the JSON contains no rows.
 	 */
-	update_cached_tupdesc(&cache->c.io.composite, cache->fn_mcxt);
+	update_cached_tupdesc(&cache->c.composite, cache->fn_mcxt);
 
 	state = palloc0(sizeof(PopulateRecordsetState));
 
@@ -4186,14 +4186,14 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
 				JsObject	obj;
 
 				if (v.type != jbvBinary ||
-					!JsonContainerIsObject(v.val.binary.data))
+					!JsonContainerIsObject(v.binary.data))
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("argument of %s must be an array of objects",
 									funcname)));
 
 				obj.is_json = false;
-				obj.val.jsonb_cont = v.val.binary.data;
+				obj.jsonb_cont = v.binary.data;
 
 				populate_recordset_record(state, &obj);
 			}
@@ -4206,7 +4206,7 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
 	 * we're called again in the same query.
 	 */
 	rsi->setResult = state->tuple_store;
-	rsi->setDesc = CreateTupleDescCopy(cache->c.io.composite.tupdesc);
+	rsi->setDesc = CreateTupleDescCopy(cache->c.composite.tupdesc);
 
 	PG_RETURN_NULL();
 }
@@ -4252,7 +4252,7 @@ populate_recordset_object_end(void *state)
 		return JSON_SUCCESS;
 
 	obj.is_json = true;
-	obj.val.json_hash = _state->json_hash;
+	obj.json_hash = _state->json_hash;
 
 	/* Otherwise, construct and return a tuple based on this level-1 object */
 	populate_recordset_record(_state, &obj);
@@ -4689,8 +4689,8 @@ jsonb_delete(PG_FUNCTION_ARGS)
 		skipNested = true;
 
 		if ((r == WJB_ELEM || r == WJB_KEY) &&
-			(v.type == jbvString && keylen == v.val.string.len &&
-			 memcmp(keyptr, v.val.string.val, keylen) == 0))
+			(v.type == jbvString && keylen == v.string.len &&
+			 memcmp(keyptr, v.string.val, keylen) == 0))
 		{
 			/* skip corresponding value as well */
 			if (r == WJB_KEY)
@@ -4768,8 +4768,8 @@ jsonb_delete_array(PG_FUNCTION_ARGS)
 				/* We rely on the array elements not being toasted */
 				keyptr = VARDATA_ANY(DatumGetPointer(keys_elems[i]));
 				keylen = VARSIZE_ANY_EXHDR(DatumGetPointer(keys_elems[i]));
-				if (keylen == v.val.string.len &&
-					memcmp(keyptr, v.val.string.val, keylen) == 0)
+				if (keylen == v.string.len &&
+					memcmp(keyptr, v.string.val, keylen) == 0)
 				{
 					found = true;
 					break;
@@ -4830,7 +4830,7 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
 
 	r = JsonbIteratorNext(&it, &v, false);
 	Assert(r == WJB_BEGIN_ARRAY);
-	n = v.val.array.nElems;
+	n = v.array.nElems;
 
 	if (idx < 0)
 	{
@@ -5230,7 +5230,7 @@ setPath(JsonbIterator **it, Datum *path_elems,
 			 * an object or an array, not raw scalar.
 			 */
 			if ((op_type & JB_PATH_FILL_GAPS) && (level <= path_len - 1) &&
-				v.val.array.rawScalar)
+				v.array.rawScalar)
 				ereport(ERROR,
 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 						 errmsg("cannot replace existing key"),
@@ -5239,7 +5239,7 @@ setPath(JsonbIterator **it, Datum *path_elems,
 
 			(void) pushJsonbValue(st, r, NULL);
 			setPathArray(it, path_elems, path_nulls, path_len, st, level,
-						 newval, v.val.array.nElems, op_type);
+						 newval, v.array.nElems, op_type);
 			r = JsonbIteratorNext(it, &v, false);
 			Assert(r == WJB_END_ARRAY);
 			res = pushJsonbValue(st, r, NULL);
@@ -5247,7 +5247,7 @@ setPath(JsonbIterator **it, Datum *path_elems,
 		case WJB_BEGIN_OBJECT:
 			(void) pushJsonbValue(st, r, NULL);
 			setPathObject(it, path_elems, path_nulls, path_len, st, level,
-						  newval, v.val.object.nPairs, op_type);
+						  newval, v.object.nPairs, op_type);
 			r = JsonbIteratorNext(it, &v, true);
 			Assert(r == WJB_END_OBJECT);
 			res = pushJsonbValue(st, r, NULL);
@@ -5308,8 +5308,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
 		JsonbValue	newkey;
 
 		newkey.type = jbvString;
-		newkey.val.string.val = VARDATA_ANY(pathelem);
-		newkey.val.string.len = VARSIZE_ANY_EXHDR(pathelem);
+		newkey.string.val = VARDATA_ANY(pathelem);
+		newkey.string.len = VARSIZE_ANY_EXHDR(pathelem);
 
 		(void) pushJsonbValue(st, WJB_KEY, &newkey);
 		(void) pushJsonbValue(st, WJB_VALUE, newval);
@@ -5322,9 +5322,9 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
 		Assert(r == WJB_KEY);
 
 		if (!done &&
-			k.val.string.len == VARSIZE_ANY_EXHDR(pathelem) &&
-			memcmp(k.val.string.val, VARDATA_ANY(pathelem),
-				   k.val.string.len) == 0)
+			k.string.len == VARSIZE_ANY_EXHDR(pathelem) &&
+			memcmp(k.string.val, VARDATA_ANY(pathelem),
+				   k.string.len) == 0)
 		{
 			done = true;
 
@@ -5363,8 +5363,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
 				JsonbValue	newkey;
 
 				newkey.type = jbvString;
-				newkey.val.string.val = VARDATA_ANY(pathelem);
-				newkey.val.string.len = VARSIZE_ANY_EXHDR(pathelem);
+				newkey.string.val = VARDATA_ANY(pathelem);
+				newkey.string.len = VARSIZE_ANY_EXHDR(pathelem);
 
 				(void) pushJsonbValue(st, WJB_KEY, &newkey);
 				(void) pushJsonbValue(st, WJB_VALUE, newval);
@@ -5407,8 +5407,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
 		JsonbValue	newkey;
 
 		newkey.type = jbvString;
-		newkey.val.string.val = VARDATA_ANY(pathelem);
-		newkey.val.string.len = VARSIZE_ANY_EXHDR(pathelem);
+		newkey.string.val = VARDATA_ANY(pathelem);
+		newkey.string.len = VARSIZE_ANY_EXHDR(pathelem);
 
 		(void) pushJsonbValue(st, WJB_KEY, &newkey);
 		(void) push_path(st, level, path_elems, path_nulls,
@@ -5621,26 +5621,26 @@ parse_jsonb_index_flags(Jsonb *jb)
 					 errmsg("flag array element is not a string"),
 					 errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));
 
-		if (v.val.string.len == 3 &&
-			pg_strncasecmp(v.val.string.val, "all", 3) == 0)
+		if (v.string.len == 3 &&
+			pg_strncasecmp(v.string.val, "all", 3) == 0)
 			flags |= jtiAll;
-		else if (v.val.string.len == 3 &&
-				 pg_strncasecmp(v.val.string.val, "key", 3) == 0)
+		else if (v.string.len == 3 &&
+				 pg_strncasecmp(v.string.val, "key", 3) == 0)
 			flags |= jtiKey;
-		else if (v.val.string.len == 6 &&
-				 pg_strncasecmp(v.val.string.val, "string", 6) == 0)
+		else if (v.string.len == 6 &&
+				 pg_strncasecmp(v.string.val, "string", 6) == 0)
 			flags |= jtiString;
-		else if (v.val.string.len == 7 &&
-				 pg_strncasecmp(v.val.string.val, "numeric", 7) == 0)
+		else if (v.string.len == 7 &&
+				 pg_strncasecmp(v.string.val, "numeric", 7) == 0)
 			flags |= jtiNumeric;
-		else if (v.val.string.len == 7 &&
-				 pg_strncasecmp(v.val.string.val, "boolean", 7) == 0)
+		else if (v.string.len == 7 &&
+				 pg_strncasecmp(v.string.val, "boolean", 7) == 0)
 			flags |= jtiBool;
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("wrong flag in flag array: \"%s\"",
-							pnstrdup(v.val.string.val, v.val.string.len)),
+							pnstrdup(v.string.val, v.string.len)),
 					 errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));
 	}
 
@@ -5679,7 +5679,7 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state,
 		if (type == WJB_KEY)
 		{
 			if (flags & jtiKey)
-				action(state, v.val.string.val, v.val.string.len);
+				action(state, v.string.val, v.string.len);
 
 			continue;
 		}
@@ -5694,7 +5694,7 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state,
 		{
 			case jbvString:
 				if (flags & jtiString)
-					action(state, v.val.string.val, v.val.string.len);
+					action(state, v.string.val, v.string.len);
 				break;
 			case jbvNumeric:
 				if (flags & jtiNumeric)
@@ -5702,7 +5702,7 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state,
 					char	   *val;
 
 					val = DatumGetCString(DirectFunctionCall1(numeric_out,
-															  NumericGetDatum(v.val.numeric)));
+															  NumericGetDatum(v.numeric)));
 
 					action(state, val, strlen(val));
 					pfree(val);
@@ -5711,7 +5711,7 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state,
 			case jbvBool:
 				if (flags & jtiBool)
 				{
-					if (v.val.boolean)
+					if (v.boolean)
 						action(state, "true", 4);
 					else
 						action(state, "false", 5);
@@ -5821,11 +5821,11 @@ transform_jsonb_string_values(Jsonb *jsonb, void *action_state,
 	{
 		if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
 		{
-			out = transform_action(action_state, v.val.string.val, v.val.string.len);
+			out = transform_action(action_state, v.string.val, v.string.len);
 			/* out is probably not toasted, but let's be sure */
 			out = pg_detoast_datum_packed(out);
-			v.val.string.val = VARDATA_ANY(out);
-			v.val.string.len = VARSIZE_ANY_EXHDR(out);
+			v.string.val = VARDATA_ANY(out);
+			v.string.len = VARSIZE_ANY_EXHDR(out);
 			res = pushJsonbValue(&st, type, type < WJB_BEGIN_ARRAY ? &v : NULL);
 		}
 		else
@@ -5837,7 +5837,7 @@ transform_jsonb_string_values(Jsonb *jsonb, void *action_state,
 	}
 
 	if (res->type == jbvArray)
-		res->val.array.rawScalar = is_scalar;
+		res->array.rawScalar = is_scalar;
 
 	return JsonbValueToJsonb(res);
 }
diff --git a/src/backend/utils/adt/jsonpath.c b/src/backend/utils/adt/jsonpath.c
index 762f7e8a09d..65172405b6a 100644
--- a/src/backend/utils/adt/jsonpath.c
+++ b/src/backend/utils/adt/jsonpath.c
@@ -269,19 +269,19 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 		case jpiString:
 		case jpiVariable:
 		case jpiKey:
-			appendBinaryStringInfo(buf, &item->value.string.len,
-								   sizeof(item->value.string.len));
-			appendBinaryStringInfo(buf, item->value.string.val,
-								   item->value.string.len);
+			appendBinaryStringInfo(buf, &item->string.len,
+								   sizeof(item->string.len));
+			appendBinaryStringInfo(buf, item->string.val,
+								   item->string.len);
 			appendStringInfoChar(buf, '\0');
 			break;
 		case jpiNumeric:
-			appendBinaryStringInfo(buf, item->value.numeric,
-								   VARSIZE(item->value.numeric));
+			appendBinaryStringInfo(buf, item->numeric,
+								   VARSIZE(item->numeric));
 			break;
 		case jpiBool:
-			appendBinaryStringInfo(buf, &item->value.boolean,
-								   sizeof(item->value.boolean));
+			appendBinaryStringInfo(buf, &item->boolean,
+								   sizeof(item->boolean));
 			break;
 		case jpiAnd:
 		case jpiOr:
@@ -307,19 +307,19 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 				int32		left = reserveSpaceForItemPointer(buf);
 				int32		right = reserveSpaceForItemPointer(buf);
 
-				if (!item->value.args.left)
+				if (!item->args.left)
 					chld = pos;
 				else if (!flattenJsonPathParseItem(buf, &chld, escontext,
-												   item->value.args.left,
+												   item->args.left,
 												   nestingLevel + argNestingLevel,
 												   insideArraySubscript))
 					return false;
 				*(int32 *) (buf->data + left) = chld - pos;
 
-				if (!item->value.args.right)
+				if (!item->args.right)
 					chld = pos;
 				else if (!flattenJsonPathParseItem(buf, &chld, escontext,
-												   item->value.args.right,
+												   item->args.right,
 												   nestingLevel + argNestingLevel,
 												   insideArraySubscript))
 					return false;
@@ -331,18 +331,18 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 				int32		offs;
 
 				appendBinaryStringInfo(buf,
-									   &item->value.like_regex.flags,
-									   sizeof(item->value.like_regex.flags));
+									   &item->like_regex.flags,
+									   sizeof(item->like_regex.flags));
 				offs = reserveSpaceForItemPointer(buf);
 				appendBinaryStringInfo(buf,
-									   &item->value.like_regex.patternlen,
-									   sizeof(item->value.like_regex.patternlen));
-				appendBinaryStringInfo(buf, item->value.like_regex.pattern,
-									   item->value.like_regex.patternlen);
+									   &item->like_regex.patternlen,
+									   sizeof(item->like_regex.patternlen));
+				appendBinaryStringInfo(buf, item->like_regex.pattern,
+									   item->like_regex.patternlen);
 				appendStringInfoChar(buf, '\0');
 
 				if (!flattenJsonPathParseItem(buf, &chld, escontext,
-											  item->value.like_regex.expr,
+											  item->like_regex.expr,
 											  nestingLevel,
 											  insideArraySubscript))
 					return false;
@@ -365,10 +365,10 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 			{
 				int32		arg = reserveSpaceForItemPointer(buf);
 
-				if (!item->value.arg)
+				if (!item->arg)
 					chld = pos;
 				else if (!flattenJsonPathParseItem(buf, &chld, escontext,
-												   item->value.arg,
+												   item->arg,
 												   nestingLevel + argNestingLevel,
 												   insideArraySubscript))
 					return false;
@@ -396,7 +396,7 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 			break;
 		case jpiIndexArray:
 			{
-				int32		nelems = item->value.array.nelems;
+				int32		nelems = item->array.nelems;
 				int			offset;
 				int			i;
 
@@ -413,15 +413,15 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 					int32		frompos;
 
 					if (!flattenJsonPathParseItem(buf, &frompos, escontext,
-												  item->value.array.elems[i].from,
+												  item->array.elems[i].from,
 												  nestingLevel, true))
 						return false;
 					frompos -= pos;
 
-					if (item->value.array.elems[i].to)
+					if (item->array.elems[i].to)
 					{
 						if (!flattenJsonPathParseItem(buf, &topos, escontext,
-													  item->value.array.elems[i].to,
+													  item->array.elems[i].to,
 													  nestingLevel, true))
 							return false;
 						topos -= pos;
@@ -438,11 +438,11 @@ flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext,
 			break;
 		case jpiAny:
 			appendBinaryStringInfo(buf,
-								   &item->value.anybounds.first,
-								   sizeof(item->value.anybounds.first));
+								   &item->anybounds.first,
+								   sizeof(item->anybounds.first));
 			appendBinaryStringInfo(buf,
-								   &item->value.anybounds.last,
-								   sizeof(item->value.anybounds.last));
+								   &item->anybounds.last,
+								   sizeof(item->anybounds.last));
 			break;
 		case jpiType:
 		case jpiSize:
@@ -617,7 +617,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiIndexArray:
 			appendStringInfoChar(buf, '[');
-			for (i = 0; i < v->content.array.nelems; i++)
+			for (i = 0; i < v->array.nelems; i++)
 			{
 				JsonPathItem from;
 				JsonPathItem to;
@@ -640,27 +640,27 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			if (inKey)
 				appendStringInfoChar(buf, '.');
 
-			if (v->content.anybounds.first == 0 &&
-				v->content.anybounds.last == PG_UINT32_MAX)
+			if (v->anybounds.first == 0 &&
+				v->anybounds.last == PG_UINT32_MAX)
 				appendStringInfoString(buf, "**");
-			else if (v->content.anybounds.first == v->content.anybounds.last)
+			else if (v->anybounds.first == v->anybounds.last)
 			{
-				if (v->content.anybounds.first == PG_UINT32_MAX)
+				if (v->anybounds.first == PG_UINT32_MAX)
 					appendStringInfoString(buf, "**{last}");
 				else
 					appendStringInfo(buf, "**{%u}",
-									 v->content.anybounds.first);
+									 v->anybounds.first);
 			}
-			else if (v->content.anybounds.first == PG_UINT32_MAX)
+			else if (v->anybounds.first == PG_UINT32_MAX)
 				appendStringInfo(buf, "**{last to %u}",
-								 v->content.anybounds.last);
-			else if (v->content.anybounds.last == PG_UINT32_MAX)
+								 v->anybounds.last);
+			else if (v->anybounds.last == PG_UINT32_MAX)
 				appendStringInfo(buf, "**{%u to last}",
-								 v->content.anybounds.first);
+								 v->anybounds.first);
 			else
 				appendStringInfo(buf, "**{%u to %u}",
-								 v->content.anybounds.first,
-								 v->content.anybounds.last);
+								 v->anybounds.first,
+								 v->anybounds.last);
 			break;
 		case jpiKey:
 			if (inKey)
@@ -713,7 +713,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiDatetime:
 			appendStringInfoString(buf, ".datetime(");
-			if (v->content.arg)
+			if (v->arg)
 			{
 				jspGetArg(v, &elem);
 				printJsonPathItem(buf, &elem, false, false);
@@ -730,7 +730,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			if (printBracketes)
 				appendStringInfoChar(buf, '(');
 
-			jspInitByBuffer(&elem, v->base, v->content.like_regex.expr);
+			jspInitByBuffer(&elem, v->base, v->like_regex.expr);
 			printJsonPathItem(buf, &elem, false,
 							  operationPriority(elem.type) <=
 							  operationPriority(v->type));
@@ -738,22 +738,22 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			appendStringInfoString(buf, " like_regex ");
 
 			escape_json_with_len(buf,
-								 v->content.like_regex.pattern,
-								 v->content.like_regex.patternlen);
+								 v->like_regex.pattern,
+								 v->like_regex.patternlen);
 
-			if (v->content.like_regex.flags)
+			if (v->like_regex.flags)
 			{
 				appendStringInfoString(buf, " flag \"");
 
-				if (v->content.like_regex.flags & JSP_REGEX_ICASE)
+				if (v->like_regex.flags & JSP_REGEX_ICASE)
 					appendStringInfoChar(buf, 'i');
-				if (v->content.like_regex.flags & JSP_REGEX_DOTALL)
+				if (v->like_regex.flags & JSP_REGEX_DOTALL)
 					appendStringInfoChar(buf, 's');
-				if (v->content.like_regex.flags & JSP_REGEX_MLINE)
+				if (v->like_regex.flags & JSP_REGEX_MLINE)
 					appendStringInfoChar(buf, 'm');
-				if (v->content.like_regex.flags & JSP_REGEX_WSPACE)
+				if (v->like_regex.flags & JSP_REGEX_WSPACE)
 					appendStringInfoChar(buf, 'x');
-				if (v->content.like_regex.flags & JSP_REGEX_QUOTE)
+				if (v->like_regex.flags & JSP_REGEX_QUOTE)
 					appendStringInfoChar(buf, 'q');
 
 				appendStringInfoChar(buf, '"');
@@ -773,12 +773,12 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiDecimal:
 			appendStringInfoString(buf, ".decimal(");
-			if (v->content.args.left)
+			if (v->args.left)
 			{
 				jspGetLeftArg(v, &elem);
 				printJsonPathItem(buf, &elem, false, false);
 			}
-			if (v->content.args.right)
+			if (v->args.right)
 			{
 				appendStringInfoChar(buf, ',');
 				jspGetRightArg(v, &elem);
@@ -797,7 +797,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiTime:
 			appendStringInfoString(buf, ".time(");
-			if (v->content.arg)
+			if (v->arg)
 			{
 				jspGetArg(v, &elem);
 				printJsonPathItem(buf, &elem, false, false);
@@ -806,7 +806,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiTimeTz:
 			appendStringInfoString(buf, ".time_tz(");
-			if (v->content.arg)
+			if (v->arg)
 			{
 				jspGetArg(v, &elem);
 				printJsonPathItem(buf, &elem, false, false);
@@ -815,7 +815,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiTimestamp:
 			appendStringInfoString(buf, ".timestamp(");
-			if (v->content.arg)
+			if (v->arg)
 			{
 				jspGetArg(v, &elem);
 				printJsonPathItem(buf, &elem, false, false);
@@ -824,7 +824,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
 			break;
 		case jpiTimestampTz:
 			appendStringInfoString(buf, ".timestamp_tz(");
-			if (v->content.arg)
+			if (v->arg)
 			{
 				jspGetArg(v, &elem);
 				printJsonPathItem(buf, &elem, false, false);
@@ -1020,11 +1020,11 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
 		case jpiString:
 		case jpiKey:
 		case jpiVariable:
-			read_int32(v->content.value.datalen, base, pos);
+			read_int32(v->value.datalen, base, pos);
 			/* FALLTHROUGH */
 		case jpiNumeric:
 		case jpiBool:
-			v->content.value.data = base + pos;
+			v->value.data = base + pos;
 			break;
 		case jpiAnd:
 		case jpiOr:
@@ -1041,8 +1041,8 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
 		case jpiMod:
 		case jpiStartsWith:
 		case jpiDecimal:
-			read_int32(v->content.args.left, base, pos);
-			read_int32(v->content.args.right, base, pos);
+			read_int32(v->args.left, base, pos);
+			read_int32(v->args.right, base, pos);
 			break;
 		case jpiNot:
 		case jpiIsUnknown:
@@ -1055,22 +1055,22 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
 		case jpiTimeTz:
 		case jpiTimestamp:
 		case jpiTimestampTz:
-			read_int32(v->content.arg, base, pos);
+			read_int32(v->arg, base, pos);
 			break;
 		case jpiIndexArray:
-			read_int32(v->content.array.nelems, base, pos);
-			read_int32_n(v->content.array.elems, base, pos,
-						 v->content.array.nelems * 2);
+			read_int32(v->array.nelems, base, pos);
+			read_int32_n(v->array.elems, base, pos,
+						 v->array.nelems * 2);
 			break;
 		case jpiAny:
-			read_int32(v->content.anybounds.first, base, pos);
-			read_int32(v->content.anybounds.last, base, pos);
+			read_int32(v->anybounds.first, base, pos);
+			read_int32(v->anybounds.last, base, pos);
 			break;
 		case jpiLikeRegex:
-			read_int32(v->content.like_regex.flags, base, pos);
-			read_int32(v->content.like_regex.expr, base, pos);
-			read_int32(v->content.like_regex.patternlen, base, pos);
-			v->content.like_regex.pattern = base + pos;
+			read_int32(v->like_regex.flags, base, pos);
+			read_int32(v->like_regex.expr, base, pos);
+			read_int32(v->like_regex.patternlen, base, pos);
+			v->like_regex.pattern = base + pos;
 			break;
 		default:
 			elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
@@ -1092,7 +1092,7 @@ jspGetArg(JsonPathItem *v, JsonPathItem *a)
 		   v->type == jpiTimestamp ||
 		   v->type == jpiTimestampTz);
 
-	jspInitByBuffer(a, v->base, v->content.arg);
+	jspInitByBuffer(a, v->base, v->arg);
 }
 
 bool
@@ -1181,7 +1181,7 @@ jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
 		   v->type == jpiStartsWith ||
 		   v->type == jpiDecimal);
 
-	jspInitByBuffer(a, v->base, v->content.args.left);
+	jspInitByBuffer(a, v->base, v->args.left);
 }
 
 void
@@ -1203,7 +1203,7 @@ jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
 		   v->type == jpiStartsWith ||
 		   v->type == jpiDecimal);
 
-	jspInitByBuffer(a, v->base, v->content.args.right);
+	jspInitByBuffer(a, v->base, v->args.right);
 }
 
 bool
@@ -1211,7 +1211,7 @@ jspGetBool(JsonPathItem *v)
 {
 	Assert(v->type == jpiBool);
 
-	return (bool) *v->content.value.data;
+	return (bool) *v->value.data;
 }
 
 Numeric
@@ -1219,7 +1219,7 @@ jspGetNumeric(JsonPathItem *v)
 {
 	Assert(v->type == jpiNumeric);
 
-	return (Numeric) v->content.value.data;
+	return (Numeric) v->value.data;
 }
 
 char *
@@ -1230,8 +1230,8 @@ jspGetString(JsonPathItem *v, int32 *len)
 		   v->type == jpiVariable);
 
 	if (len)
-		*len = v->content.value.datalen;
-	return v->content.value.data;
+		*len = v->value.datalen;
+	return v->value.data;
 }
 
 bool
@@ -1240,12 +1240,12 @@ jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to,
 {
 	Assert(v->type == jpiIndexArray);
 
-	jspInitByBuffer(from, v->base, v->content.array.elems[i].from);
+	jspInitByBuffer(from, v->base, v->array.elems[i].from);
 
-	if (!v->content.array.elems[i].to)
+	if (!v->array.elems[i].to)
 		return false;
 
-	jspInitByBuffer(to, v->base, v->content.array.elems[i].to);
+	jspInitByBuffer(to, v->base, v->array.elems[i].to);
 
 	return true;
 }
@@ -1423,7 +1423,7 @@ jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
 				break;
 
 			case jpiIndexArray:
-				for (int i = 0; i < jpi->content.array.nelems; i++)
+				for (int i = 0; i < jpi->array.nelems; i++)
 				{
 					JsonPathItem from;
 					JsonPathItem to;
@@ -1441,12 +1441,12 @@ jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
 				break;
 
 			case jpiAny:
-				if (jpi->content.anybounds.first > 0)
+				if (jpi->anybounds.first > 0)
 					status = jpdsNonDateTime;
 				break;
 
 			case jpiDatetime:
-				if (jpi->content.arg)
+				if (jpi->arg)
 				{
 					char	   *template;
 
@@ -1471,7 +1471,7 @@ jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
 
 			case jpiLikeRegex:
 				Assert(status == jpdsNonDateTime);
-				jspInitByBuffer(&arg, jpi->base, jpi->content.like_regex.expr);
+				jspInitByBuffer(&arg, jpi->base, jpi->like_regex.expr);
 				jspIsMutableWalker(&arg, cxt);
 				break;
 
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 8156695e97e..779f32b4a0b 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -478,7 +478,7 @@ jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)
 		JsonbValue *jbv = JsonValueListHead(&found);
 
 		if (jbv->type == jbvBool)
-			PG_RETURN_BOOL(jbv->val.boolean);
+			PG_RETURN_BOOL(jbv->boolean);
 
 		if (jbv->type == jbvNull)
 			PG_RETURN_NULL();
@@ -860,7 +860,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				return executeAnyItem
 					(cxt, hasNext ? &elem : NULL,
-					 jb->val.binary.data, found, 1, 1, 1,
+					 jb->binary.data, found, 1, 1, 1,
 					 false, jspAutoUnwrap(cxt));
 			}
 			else if (unwrap && JsonbType(jb) == jbvArray)
@@ -888,7 +888,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				cxt->innermostArraySize = size; /* for LAST evaluation */
 
-				for (i = 0; i < jsp->content.array.nelems; i++)
+				for (i = 0; i < jsp->array.nelems; i++)
 				{
 					JsonPathItem from;
 					JsonPathItem to;
@@ -941,7 +941,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 						}
 						else
 						{
-							v = getIthJsonbValueFromContainer(jb->val.binary.data,
+							v = getIthJsonbValueFromContainer(jb->binary.data,
 															  (uint32) index);
 
 							if (v == NULL)
@@ -985,7 +985,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				bool		hasNext = jspGetNext(jsp, &elem);
 
 				/* first try without any intermediate steps */
-				if (jsp->content.anybounds.first == 0)
+				if (jsp->anybounds.first == 0)
 				{
 					bool		savedIgnoreStructuralErrors;
 
@@ -1002,10 +1002,10 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				if (jb->type == jbvBinary)
 					res = executeAnyItem
 						(cxt, hasNext ? &elem : NULL,
-						 jb->val.binary.data, found,
+						 jb->binary.data, found,
 						 1,
-						 jsp->content.anybounds.first,
-						 jsp->content.anybounds.last,
+						 jsp->anybounds.first,
+						 jsp->anybounds.last,
 						 true, jspAutoUnwrap(cxt));
 				break;
 			}
@@ -1017,9 +1017,9 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				JsonbValue	key;
 
 				key.type = jbvString;
-				key.val.string.val = jspGetString(jsp, &key.val.string.len);
+				key.string.val = jspGetString(jsp, &key.string.len);
 
-				v = findJsonbValueFromContainer(jb->val.binary.data,
+				v = findJsonbValueFromContainer(jb->binary.data,
 												JB_FOBJECT, &key);
 
 				if (v != NULL)
@@ -1041,8 +1041,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					ereport(ERROR,
 							(errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \
 							 errmsg("JSON object does not contain key \"%s\"",
-									pnstrdup(key.val.string.val,
-											 key.val.string.len))));
+									pnstrdup(key.string.val,
+											 key.string.len))));
 				}
 			}
 			else if (unwrap && JsonbType(jb) == jbvArray)
@@ -1091,8 +1091,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				JsonbValue *jbv = palloc(sizeof(*jbv));
 
 				jbv->type = jbvString;
-				jbv->val.string.val = pstrdup(JsonbTypeName(jb));
-				jbv->val.string.len = strlen(jbv->val.string.val);
+				jbv->string.val = pstrdup(JsonbTypeName(jb));
+				jbv->string.len = strlen(jbv->string.val);
 
 				res = executeNextItem(cxt, jsp, NULL, jbv,
 									  found, false);
@@ -1121,7 +1121,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				jb = palloc(sizeof(*jb));
 
 				jb->type = jbvNumeric;
-				jb->val.numeric = int64_to_numeric(size);
+				jb->numeric = int64_to_numeric(size);
 
 				res = executeNextItem(cxt, jsp, NULL, jb, found, false);
 			}
@@ -1150,7 +1150,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				if (jb->type == jbvNumeric)
 				{
 					char	   *tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
-																		  NumericGetDatum(jb->val.numeric)));
+																		  NumericGetDatum(jb->numeric)));
 					double		val;
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 
@@ -1176,8 +1176,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				{
 					/* cast string as double */
 					double		val;
-					char	   *tmp = pnstrdup(jb->val.string.val,
-											   jb->val.string.len);
+					char	   *tmp = pnstrdup(jb->string.val,
+											   jb->string.len);
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 
 					val = float8in_internal(tmp,
@@ -1199,8 +1199,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 					jb = &jbv;
 					jb->type = jbvNumeric;
-					jb->val.numeric = DatumGetNumeric(DirectFunctionCall1(float8_numeric,
-																		  Float8GetDatum(val)));
+					jb->numeric = DatumGetNumeric(DirectFunctionCall1(float8_numeric,
+																	  Float8GetDatum(val)));
 					res = jperOk;
 				}
 
@@ -1252,7 +1252,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv));
 
 				lastjbv->type = jbvNumeric;
-				lastjbv->val.numeric = int64_to_numeric(last);
+				lastjbv->numeric = int64_to_numeric(last);
 
 				res = executeNextItem(cxt, jsp, &elem,
 									  lastjbv, found, hasNext);
@@ -1273,14 +1273,14 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 					int64		val;
 
-					val = numeric_int8_safe(jb->val.numeric,
+					val = numeric_int8_safe(jb->numeric,
 											(Node *) &escontext);
 					if (escontext.error_occurred)
 						RETURN_ERROR(ereport(ERROR,
 											 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
 											  errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
 													 DatumGetCString(DirectFunctionCall1(numeric_out,
-																						 NumericGetDatum(jb->val.numeric))),
+																						 NumericGetDatum(jb->numeric))),
 													 jspOperationName(jsp->type),
 													 "bigint"))));
 
@@ -1290,8 +1290,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				else if (jb->type == jbvString)
 				{
 					/* cast string as bigint */
-					char	   *tmp = pnstrdup(jb->val.string.val,
-											   jb->val.string.len);
+					char	   *tmp = pnstrdup(jb->string.val,
+											   jb->string.len);
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 					bool		noerr;
 
@@ -1316,8 +1316,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				jb = &jbv;
 				jb->type = jbvNumeric;
-				jb->val.numeric = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
-																	  datum));
+				jb->numeric = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
+																  datum));
 
 				res = executeNextItem(cxt, jsp, NULL, jb, found, true);
 			}
@@ -1334,7 +1334,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				if (jb->type == jbvBool)
 				{
-					bval = jb->val.boolean;
+					bval = jb->boolean;
 
 					res = jperOk;
 				}
@@ -1344,7 +1344,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					Datum		datum;
 					bool		noerr;
 					char	   *tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
-																		  NumericGetDatum(jb->val.numeric)));
+																		  NumericGetDatum(jb->numeric)));
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 
 					noerr = DirectInputFunctionCallSafe(int4in, tmp,
@@ -1369,8 +1369,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				else if (jb->type == jbvString)
 				{
 					/* cast string as boolean */
-					char	   *tmp = pnstrdup(jb->val.string.val,
-											   jb->val.string.len);
+					char	   *tmp = pnstrdup(jb->string.val,
+											   jb->string.len);
 
 					if (!parse_bool(tmp, &bval))
 						RETURN_ERROR(ereport(ERROR,
@@ -1389,7 +1389,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				jb = &jbv;
 				jb->type = jbvBool;
-				jb->val.boolean = bval;
+				jb->boolean = bval;
 
 				res = executeNextItem(cxt, jsp, NULL, jb, found, true);
 			}
@@ -1408,7 +1408,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				if (jb->type == jbvNumeric)
 				{
-					num = jb->val.numeric;
+					num = jb->numeric;
 					if (numeric_is_nan(num) || numeric_is_inf(num))
 						RETURN_ERROR(ereport(ERROR,
 											 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
@@ -1427,7 +1427,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					bool		noerr;
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-					numstr = pnstrdup(jb->val.string.val, jb->val.string.len);
+					numstr = pnstrdup(jb->string.val, jb->string.len);
 
 					noerr = DirectInputFunctionCallSafe(numeric_in, numstr,
 														InvalidOid, -1,
@@ -1462,7 +1462,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				 * typmod equivalent and then truncate the numeric value per
 				 * this typmod details.
 				 */
-				if (jsp->type == jpiDecimal && jsp->content.args.left)
+				if (jsp->type == jpiDecimal && jsp->args.left)
 				{
 					Datum		numdatum;
 					Datum		dtypmod;
@@ -1487,7 +1487,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 											  errmsg("precision of jsonpath item method .%s() is out of range for type integer",
 													 jspOperationName(jsp->type)))));
 
-					if (jsp->content.args.right)
+					if (jsp->args.right)
 					{
 						jspGetRightArg(jsp, &elem);
 						if (elem.type != jpiNumeric)
@@ -1534,7 +1534,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				jb = &jbv;
 				jb->type = jbvNumeric;
-				jb->val.numeric = num;
+				jb->numeric = num;
 
 				res = executeNextItem(cxt, jsp, NULL, jb, found, true);
 			}
@@ -1554,14 +1554,14 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 					int32		val;
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-					val = numeric_int4_safe(jb->val.numeric,
+					val = numeric_int4_safe(jb->numeric,
 											(Node *) &escontext);
 					if (escontext.error_occurred)
 						RETURN_ERROR(ereport(ERROR,
 											 (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
 											  errmsg("argument \"%s\" of jsonpath item method .%s() is invalid for type %s",
 													 DatumGetCString(DirectFunctionCall1(numeric_out,
-																						 NumericGetDatum(jb->val.numeric))),
+																						 NumericGetDatum(jb->numeric))),
 													 jspOperationName(jsp->type), "integer"))));
 
 					datum = Int32GetDatum(val);
@@ -1570,8 +1570,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				else if (jb->type == jbvString)
 				{
 					/* cast string as integer */
-					char	   *tmp = pnstrdup(jb->val.string.val,
-											   jb->val.string.len);
+					char	   *tmp = pnstrdup(jb->string.val,
+											   jb->string.len);
 					ErrorSaveContext escontext = {T_ErrorSaveContext};
 					bool		noerr;
 
@@ -1596,8 +1596,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				jb = &jbv;
 				jb->type = jbvNumeric;
-				jb->val.numeric = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
-																	  datum));
+				jb->numeric = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
+																  datum));
 
 				res = executeNextItem(cxt, jsp, NULL, jb, found, true);
 			}
@@ -1619,24 +1619,24 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 						 * Value is not necessarily null-terminated, so we do
 						 * pnstrdup() here.
 						 */
-						tmp = pnstrdup(jb->val.string.val,
-									   jb->val.string.len);
+						tmp = pnstrdup(jb->string.val,
+									   jb->string.len);
 						break;
 					case jbvNumeric:
 						tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
-																  NumericGetDatum(jb->val.numeric)));
+																  NumericGetDatum(jb->numeric)));
 						break;
 					case jbvBool:
-						tmp = (jb->val.boolean) ? "true" : "false";
+						tmp = (jb->boolean) ? "true" : "false";
 						break;
 					case jbvDatetime:
 						{
 							char		buf[MAXDATELEN + 1];
 
 							JsonEncodeDateTime(buf,
-											   jb->val.datetime.value,
-											   jb->val.datetime.typid,
-											   &jb->val.datetime.tz);
+											   jb->datetime.value,
+											   jb->datetime.typid,
+											   &jb->datetime.tz);
 							tmp = pstrdup(buf);
 						}
 						break;
@@ -1653,8 +1653,8 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 				jb = &jbv;
 				Assert(tmp != NULL);	/* We must have set tmp above */
-				jb->val.string.val = tmp;
-				jb->val.string.len = strlen(jb->val.string.val);
+				jb->string.val = tmp;
+				jb->string.len = strlen(jb->string.val);
 				jb->type = jbvString;
 
 				res = executeNextItem(cxt, jsp, NULL, jb, found, true);
@@ -1683,7 +1683,7 @@ executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp,
 	}
 
 	return executeAnyItem
-		(cxt, jsp, jb->val.binary.data, found, 1, 1, 1,
+		(cxt, jsp, jb->binary.data, found, 1, 1, 1,
 		 false, unwrapElements);
 }
 
@@ -1863,7 +1863,7 @@ executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp,
 				JsonLikeRegexContext lrcxt = {0};
 
 				jspInitByBuffer(&larg, jsp->base,
-								jsp->content.like_regex.expr);
+								jsp->like_regex.expr);
 
 				return executePredicate(cxt, jsp, &larg, NULL, jb, false,
 										executeLikeRegex, &lrcxt);
@@ -1996,7 +1996,7 @@ executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc,
 			if (level < last && v.type == jbvBinary)
 			{
 				res = executeAnyItem
-					(cxt, jsp, v.val.binary.data, found,
+					(cxt, jsp, v.binary.data, found,
 					 level + 1, first, last,
 					 ignoreStructuralErrors, unwrapNext);
 
@@ -2147,13 +2147,13 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 	if (jspThrowErrors(cxt))
 	{
-		res = func(lval->val.numeric, rval->val.numeric, NULL);
+		res = func(lval->numeric, rval->numeric, NULL);
 	}
 	else
 	{
 		ErrorSaveContext escontext = {T_ErrorSaveContext};
 
-		res = func(lval->val.numeric, rval->val.numeric, (Node *) &escontext);
+		res = func(lval->numeric, rval->numeric, (Node *) &escontext);
 
 		if (escontext.error_occurred)
 			return jperError;
@@ -2164,7 +2164,7 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
 
 	lval = palloc(sizeof(*lval));
 	lval->type = jbvNumeric;
-	lval->val.numeric = res;
+	lval->numeric = res;
 
 	return executeNextItem(cxt, jsp, &elem, lval, found, false);
 }
@@ -2215,9 +2215,9 @@ executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
 		}
 
 		if (func)
-			val->val.numeric =
+			val->numeric =
 				DatumGetNumeric(DirectFunctionCall1(func,
-													NumericGetDatum(val->val.numeric)));
+													NumericGetDatum(val->numeric)));
 
 		jper2 = executeNextItem(cxt, jsp, &elem, val, found, false);
 
@@ -2250,10 +2250,10 @@ executeStartsWith(JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial,
 	if (!(initial = getScalar(initial, jbvString)))
 		return jpbUnknown;		/* error */
 
-	if (whole->val.string.len >= initial->val.string.len &&
-		!memcmp(whole->val.string.val,
-				initial->val.string.val,
-				initial->val.string.len))
+	if (whole->string.len >= initial->string.len &&
+		!memcmp(whole->string.val,
+				initial->string.val,
+				initial->string.len))
 		return jpbTrue;
 
 	return jpbFalse;
@@ -2277,14 +2277,14 @@ executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg,
 	if (!cxt->regex)
 	{
 		cxt->regex =
-			cstring_to_text_with_len(jsp->content.like_regex.pattern,
-									 jsp->content.like_regex.patternlen);
-		(void) jspConvertRegexFlags(jsp->content.like_regex.flags,
+			cstring_to_text_with_len(jsp->like_regex.pattern,
+									 jsp->like_regex.patternlen);
+		(void) jspConvertRegexFlags(jsp->like_regex.flags,
 									&(cxt->cflags), NULL);
 	}
 
-	if (RE_compile_and_execute(cxt->regex, str->val.string.val,
-							   str->val.string.len,
+	if (RE_compile_and_execute(cxt->regex, str->string.val,
+							   str->string.len,
 							   cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
 		return jpbTrue;
 
@@ -2312,14 +2312,14 @@ executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 							  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
 									 jspOperationName(jsp->type)))));
 
-	datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
+	datum = DirectFunctionCall1(func, NumericGetDatum(jb->numeric));
 
 	if (!jspGetNext(jsp, &next) && !found)
 		return jperOk;
 
 	jb = palloc(sizeof(*jb));
 	jb->type = jbvNumeric;
-	jb->val.numeric = DatumGetNumeric(datum);
+	jb->numeric = DatumGetNumeric(datum);
 
 	return executeNextItem(cxt, jsp, &next, jb, found, false);
 }
@@ -2358,8 +2358,8 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 							  errmsg("jsonpath item method .%s() can only be applied to a string",
 									 jspOperationName(jsp->type)))));
 
-	datetime = cstring_to_text_with_len(jb->val.string.val,
-										jb->val.string.len);
+	datetime = cstring_to_text_with_len(jb->string.val,
+										jb->string.len);
 
 	/*
 	 * At some point we might wish to have callers supply the collation to
@@ -2372,7 +2372,7 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 	 * .datetime(template) has an argument, the rest of the methods don't have
 	 * an argument.  So we handle that separately.
 	 */
-	if (jsp->type == jpiDatetime && jsp->content.arg)
+	if (jsp->type == jpiDatetime && jsp->arg)
 	{
 		text	   *template;
 		char	   *template_str;
@@ -2433,7 +2433,7 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 		 * .date()
 		 */
 		if (jsp->type != jpiDatetime && jsp->type != jpiDate &&
-			jsp->content.arg)
+			jsp->arg)
 		{
 			ErrorSaveContext escontext = {T_ErrorSaveContext};
 
@@ -2786,10 +2786,10 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 	jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));
 
 	jb->type = jbvDatetime;
-	jb->val.datetime.value = value;
-	jb->val.datetime.typid = typid;
-	jb->val.datetime.typmod = typmod;
-	jb->val.datetime.tz = tz;
+	jb->datetime.value = value;
+	jb->datetime.typid = typid;
+	jb->datetime.typmod = typmod;
+	jb->datetime.tz = tz;
 
 	return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);
 }
@@ -2841,7 +2841,7 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 							  errmsg("jsonpath item method .%s() can only be applied to an object",
 									 jspOperationName(jsp->type)))));
 
-	jbc = jb->val.binary.data;
+	jbc = jb->binary.data;
 
 	if (!JsonContainerSize(jbc))
 		return jperNotFound;	/* no key-value pairs */
@@ -2849,16 +2849,16 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 	hasNext = jspGetNext(jsp, &next);
 
 	keystr.type = jbvString;
-	keystr.val.string.val = "key";
-	keystr.val.string.len = 3;
+	keystr.string.val = "key";
+	keystr.string.len = 3;
 
 	valstr.type = jbvString;
-	valstr.val.string.val = "value";
-	valstr.val.string.len = 5;
+	valstr.string.val = "value";
+	valstr.string.len = 5;
 
 	idstr.type = jbvString;
-	idstr.val.string.val = "id";
-	idstr.val.string.len = 2;
+	idstr.string.val = "id";
+	idstr.string.len = 2;
 
 	/* construct object id from its base object and offset inside that */
 	id = jb->type != jbvBinary ? 0 :
@@ -2866,7 +2866,7 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
 	id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
 
 	idval.type = jbvNumeric;
-	idval.val.numeric = int64_to_numeric(id);
+	idval.numeric = int64_to_numeric(id);
 
 	it = JsonbIteratorInit(jbc);
 
@@ -2944,7 +2944,7 @@ appendBoolResult(JsonPathExecContext *cxt, JsonPathItem *jsp,
 	else
 	{
 		jbv.type = jbvBool;
-		jbv.val.boolean = res == jpbTrue;
+		jbv.boolean = res == jpbTrue;
 	}
 
 	return executeNextItem(cxt, jsp, &next, &jbv, found, true);
@@ -2966,16 +2966,16 @@ getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item,
 			break;
 		case jpiBool:
 			value->type = jbvBool;
-			value->val.boolean = jspGetBool(item);
+			value->boolean = jspGetBool(item);
 			break;
 		case jpiNumeric:
 			value->type = jbvNumeric;
-			value->val.numeric = jspGetNumeric(item);
+			value->numeric = jspGetNumeric(item);
 			break;
 		case jpiString:
 			value->type = jbvString;
-			value->val.string.val = jspGetString(item,
-												 &value->val.string.len);
+			value->string.val = jspGetString(item,
+											 &value->string.len);
 			break;
 		case jpiVariable:
 			getJsonPathVariable(cxt, item, value);
@@ -3053,7 +3053,7 @@ JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)
 	{
 		case BOOLOID:
 			res->type = jbvBool;
-			res->val.boolean = DatumGetBool(val);
+			res->boolean = DatumGetBool(val);
 			break;
 		case NUMERICOID:
 			JsonbValueInitNumericDatum(res, val);
@@ -3076,8 +3076,8 @@ JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)
 		case TEXTOID:
 		case VARCHAROID:
 			res->type = jbvString;
-			res->val.string.val = VARDATA_ANY(DatumGetPointer(val));
-			res->val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(val));
+			res->string.val = VARDATA_ANY(DatumGetPointer(val));
+			res->string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(val));
 			break;
 		case DATEOID:
 		case TIMEOID:
@@ -3085,10 +3085,10 @@ JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)
 		case TIMESTAMPOID:
 		case TIMESTAMPTZOID:
 			res->type = jbvDatetime;
-			res->val.datetime.value = val;
-			res->val.datetime.typid = typid;
-			res->val.datetime.typmod = typmod;
-			res->val.datetime.tz = 0;
+			res->datetime.value = val;
+			res->datetime.typid = typid;
+			res->datetime.typmod = typmod;
+			res->datetime.tz = 0;
 			break;
 		case JSONBOID:
 			{
@@ -3132,7 +3132,7 @@ static void
 JsonbValueInitNumericDatum(JsonbValue *jbv, Datum num)
 {
 	jbv->type = jbvNumeric;
-	jbv->val.numeric = DatumGetNumeric(num);
+	jbv->numeric = DatumGetNumeric(num);
 }
 
 /*
@@ -3179,8 +3179,8 @@ getJsonPathVariableFromJsonb(void *varsJsonb, char *varName, int varNameLength,
 	JsonbValue *result;
 
 	tmp.type = jbvString;
-	tmp.val.string.val = varName;
-	tmp.val.string.len = varNameLength;
+	tmp.string.val = varName;
+	tmp.string.len = varNameLength;
 
 	result = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp);
 
@@ -3229,7 +3229,7 @@ JsonbArraySize(JsonbValue *jb)
 
 	if (jb->type == jbvBinary)
 	{
-		JsonbContainer *jbc = jb->val.binary.data;
+		JsonbContainer *jbc = jb->binary.data;
 
 		if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc))
 			return JsonContainerSize(jbc);
@@ -3364,30 +3364,30 @@ compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)
 			cmp = 0;
 			break;
 		case jbvBool:
-			cmp = jb1->val.boolean == jb2->val.boolean ? 0 :
-				jb1->val.boolean ? 1 : -1;
+			cmp = jb1->boolean == jb2->boolean ? 0 :
+				jb1->boolean ? 1 : -1;
 			break;
 		case jbvNumeric:
-			cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric);
+			cmp = compareNumeric(jb1->numeric, jb2->numeric);
 			break;
 		case jbvString:
 			if (op == jpiEqual)
-				return jb1->val.string.len != jb2->val.string.len ||
-					memcmp(jb1->val.string.val,
-						   jb2->val.string.val,
-						   jb1->val.string.len) ? jpbFalse : jpbTrue;
+				return jb1->string.len != jb2->string.len ||
+					memcmp(jb1->string.val,
+						   jb2->string.val,
+						   jb1->string.len) ? jpbFalse : jpbTrue;
 
-			cmp = compareStrings(jb1->val.string.val, jb1->val.string.len,
-								 jb2->val.string.val, jb2->val.string.len);
+			cmp = compareStrings(jb1->string.val, jb1->string.len,
+								 jb2->string.val, jb2->string.len);
 			break;
 		case jbvDatetime:
 			{
 				bool		cast_error;
 
-				cmp = compareDatetime(jb1->val.datetime.value,
-									  jb1->val.datetime.typid,
-									  jb2->val.datetime.value,
-									  jb2->val.datetime.typid,
+				cmp = compareDatetime(jb1->datetime.value,
+									  jb1->datetime.typid,
+									  jb2->datetime.value,
+									  jb2->datetime.typid,
 									  useTz,
 									  &cast_error);
 
@@ -3476,7 +3476,7 @@ getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
 							  errmsg("jsonpath array subscript is not a single numeric value"))));
 
 	numeric_index = DirectFunctionCall2(numeric_trunc,
-										NumericGetDatum(jbv->val.numeric),
+										NumericGetDatum(jbv->numeric),
 										Int32GetDatum(0));
 
 	*index = numeric_int4_safe(DatumGetNumeric(numeric_index),
@@ -3497,7 +3497,7 @@ setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
 	JsonBaseObjectInfo baseObject = cxt->baseObject;
 
 	cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL :
-		(JsonbContainer *) jbv->val.binary.data;
+		(JsonbContainer *) jbv->binary.data;
 	cxt->baseObject.id = id;
 
 	return baseObject;
@@ -3602,8 +3602,8 @@ static JsonbValue *
 JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
 {
 	jbv->type = jbvBinary;
-	jbv->val.binary.data = &jb->root;
-	jbv->val.binary.len = VARSIZE_ANY_EXHDR(jb);
+	jbv->binary.data = &jb->root;
+	jbv->binary.len = VARSIZE_ANY_EXHDR(jb);
 
 	return jbv;
 }
@@ -3618,7 +3618,7 @@ JsonbType(JsonbValue *jb)
 
 	if (jb->type == jbvBinary)
 	{
-		JsonbContainer *jbc = jb->val.binary.data;
+		JsonbContainer *jbc = jb->binary.data;
 
 		/* Scalars should be always extracted during jsonpath execution. */
 		Assert(!JsonContainerIsScalar(jbc));
@@ -3640,7 +3640,7 @@ getScalar(JsonbValue *scalar, enum jbvType type)
 {
 	/* Scalars should be always extracted during jsonpath execution. */
 	Assert(scalar->type != jbvBinary ||
-		   !JsonContainerIsScalar(scalar->val.binary.data));
+		   !JsonContainerIsScalar(scalar->binary.data));
 
 	return scalar->type == type ? scalar : NULL;
 }
@@ -4052,8 +4052,8 @@ JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars,
 	}
 
 	res = JsonValueListHead(&found);
-	if (res->type == jbvBinary && JsonContainerIsScalar(res->val.binary.data))
-		JsonbExtractScalar(res->val.binary.data, res);
+	if (res->type == jbvBinary && JsonContainerIsScalar(res->binary.data))
+		JsonbExtractScalar(res->binary.data, res);
 
 	/* JSON_VALUE expects to get only scalars. */
 	if (!IsAJsonbScalar(res))
diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y
index 499745a8fef..44301b0dcc3 100644
--- a/src/backend/utils/adt/jsonpath_gram.y
+++ b/src/backend/utils/adt/jsonpath_gram.y
@@ -406,8 +406,8 @@ makeItemString(JsonPathString *s)
 	else
 	{
 		v = makeItemType(jpiString);
-		v->value.string.val = s->val;
-		v->value.string.len = s->len;
+		v->string.val = s->val;
+		v->string.len = s->len;
 	}
 
 	return v;
@@ -419,8 +419,8 @@ makeItemVariable(JsonPathString *s)
 	JsonPathParseItem *v;
 
 	v = makeItemType(jpiVariable);
-	v->value.string.val = s->val;
-	v->value.string.len = s->len;
+	v->string.val = s->val;
+	v->string.len = s->len;
 
 	return v;
 }
@@ -442,7 +442,7 @@ makeItemNumeric(JsonPathString *s)
 	JsonPathParseItem *v;
 
 	v = makeItemType(jpiNumeric);
-	v->value.numeric =
+	v->numeric =
 		DatumGetNumeric(DirectFunctionCall3(numeric_in,
 											CStringGetDatum(s->val),
 											ObjectIdGetDatum(InvalidOid),
@@ -456,7 +456,7 @@ makeItemBool(bool val)
 {
 	JsonPathParseItem *v = makeItemType(jpiBool);
 
-	v->value.boolean = val;
+	v->boolean = val;
 
 	return v;
 }
@@ -466,8 +466,8 @@ makeItemBinary(JsonPathItemType type, JsonPathParseItem *la, JsonPathParseItem *
 {
 	JsonPathParseItem *v = makeItemType(type);
 
-	v->value.args.left = la;
-	v->value.args.right = ra;
+	v->args.left = la;
+	v->args.right = ra;
 
 	return v;
 }
@@ -483,15 +483,15 @@ makeItemUnary(JsonPathItemType type, JsonPathParseItem *a)
 	if (type == jpiMinus && a->type == jpiNumeric && !a->next)
 	{
 		v = makeItemType(jpiNumeric);
-		v->value.numeric =
+		v->numeric =
 			DatumGetNumeric(DirectFunctionCall1(numeric_uminus,
-												NumericGetDatum(a->value.numeric)));
+												NumericGetDatum(a->numeric)));
 		return v;
 	}
 
 	v = makeItemType(type);
 
-	v->value.arg = a;
+	v->arg = a;
 
 	return v;
 }
@@ -531,10 +531,10 @@ makeIndexArray(List *list)
 	int			i = 0;
 
 	Assert(list != NIL);
-	v->value.array.nelems = list_length(list);
+	v->array.nelems = list_length(list);
 
-	v->value.array.elems = palloc(sizeof(v->value.array.elems[0]) *
-								  v->value.array.nelems);
+	v->array.elems = palloc(sizeof(v->array.elems[0]) *
+								  v->array.nelems);
 
 	foreach(cell, list)
 	{
@@ -542,8 +542,8 @@ makeIndexArray(List *list)
 
 		Assert(jpi->type == jpiSubscript);
 
-		v->value.array.elems[i].from = jpi->value.args.left;
-		v->value.array.elems[i++].to = jpi->value.args.right;
+		v->array.elems[i].from = jpi->args.left;
+		v->array.elems[i++].to = jpi->args.right;
 	}
 
 	return v;
@@ -554,8 +554,8 @@ makeAny(int first, int last)
 {
 	JsonPathParseItem *v = makeItemType(jpiAny);
 
-	v->value.anybounds.first = (first >= 0) ? first : PG_UINT32_MAX;
-	v->value.anybounds.last = (last >= 0) ? last : PG_UINT32_MAX;
+	v->anybounds.first = (first >= 0) ? first : PG_UINT32_MAX;
+	v->anybounds.last = (last >= 0) ? last : PG_UINT32_MAX;
 
 	return v;
 }
@@ -569,30 +569,30 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern,
 	int			i;
 	int			cflags;
 
-	v->value.like_regex.expr = expr;
-	v->value.like_regex.pattern = pattern->val;
-	v->value.like_regex.patternlen = pattern->len;
+	v->like_regex.expr = expr;
+	v->like_regex.pattern = pattern->val;
+	v->like_regex.patternlen = pattern->len;
 
 	/* Parse the flags string, convert to bitmask.  Duplicate flags are OK. */
-	v->value.like_regex.flags = 0;
+	v->like_regex.flags = 0;
 	for (i = 0; flags && i < flags->len; i++)
 	{
 		switch (flags->val[i])
 		{
 			case 'i':
-				v->value.like_regex.flags |= JSP_REGEX_ICASE;
+				v->like_regex.flags |= JSP_REGEX_ICASE;
 				break;
 			case 's':
-				v->value.like_regex.flags |= JSP_REGEX_DOTALL;
+				v->like_regex.flags |= JSP_REGEX_DOTALL;
 				break;
 			case 'm':
-				v->value.like_regex.flags |= JSP_REGEX_MLINE;
+				v->like_regex.flags |= JSP_REGEX_MLINE;
 				break;
 			case 'x':
-				v->value.like_regex.flags |= JSP_REGEX_WSPACE;
+				v->like_regex.flags |= JSP_REGEX_WSPACE;
 				break;
 			case 'q':
-				v->value.like_regex.flags |= JSP_REGEX_QUOTE;
+				v->like_regex.flags |= JSP_REGEX_QUOTE;
 				break;
 			default:
 				ereturn(escontext, false,
@@ -605,7 +605,7 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern,
 	}
 
 	/* Convert flags to what pg_regcomp needs */
-	if (!jspConvertRegexFlags(v->value.like_regex.flags, &cflags, escontext))
+	if (!jspConvertRegexFlags(v->like_regex.flags, &cflags, escontext))
 		return false;
 
 	/* check regex validity */
diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h
index fecb33b9c67..546d24cd819 100644
--- a/src/include/utils/jsonb.h
+++ b/src/include/utils/jsonb.h
@@ -291,7 +291,7 @@ struct JsonbValue
 			int			tz;		/* Numeric time zone, in seconds, for
 								 * TimestampTz data type */
 		}			datetime;
-	}			val;
+	};
 };
 
 #define IsAJsonbScalar(jsonbval)	(((jsonbval)->type >= jbvNull && \
diff --git a/src/include/utils/jsonpath.h b/src/include/utils/jsonpath.h
index 23a76d233e9..817efd8bf87 100644
--- a/src/include/utils/jsonpath.h
+++ b/src/include/utils/jsonpath.h
@@ -188,7 +188,7 @@ typedef struct JsonPathItem
 			int32		patternlen;
 			uint32		flags;
 		}			like_regex;
-	}			content;
+	};
 } JsonPathItem;
 
 #define jspHasNext(jsp) ((jsp)->nextPos > 0)
@@ -266,7 +266,7 @@ struct JsonPathParseItem
 			uint32		len;
 			char	   *val;	/* could not be not null-terminated */
 		}			string;
-	}			value;
+	};
 };
 
 typedef struct JsonPathParseResult
-- 
2.51.0

---

From: "Joel Jacobson" <[email-masked]>
Date: Tue, 23 Sep 2025 12:16:11 +0200

> (although we're not yet at the point where this should really stress

Nice, didn't know about this C11 feature.

I've eyeballed the entire output of `git diff --word-diff-regex=.` and can't see any oddities.

I've also run the full test suite and it passes.

/Joel

---

From: Nathan Bossart <[email-masked]>
Date: Tue, 23 Sep 2025 09:17:50 -0500

> one that they particularly like, we could add that one as well.

I would have used this in the DSM registry if it was available.  Patch
attached.

-- 
nathan

---

From: Chao Li <[email-masked]>
Date: Wed, 24 Sep 2025 07:19:05 +0800

> one that they particularly like, we could add that one as well.

I went through all commits and code changes are neat and clear.

But when I tried to build on my Macbook M4, it got 18 errors
against cryptohash.c:
```
cryptohash.c:108:22: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  108 |                         pg_md5_init(&ctx->data.md5);
      |                                      ~~~  ^
cryptohash.c:111:23: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  111 |                         pg_sha1_init(&ctx->data.sha1);
      |                                       ~~~  ^
cryptohash.c:114:25: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  114 |                         pg_sha224_init(&ctx->data.sha224);
      |                                         ~~~  ^
cryptohash.c:117:25: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  117 |                         pg_sha256_init(&ctx->data.sha256);
      |                                         ~~~  ^
cryptohash.c:120:25: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  120 |                         pg_sha384_init(&ctx->data.sha384);
      |                                         ~~~  ^
cryptohash.c:123:25: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  123 |                         pg_sha512_init(&ctx->data.sha512);
      |                                         ~~~  ^
cryptohash.c:144:24: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  144 |                         pg_md5_update(&ctx->data.md5, data, len);
      |                                        ~~~  ^
cryptohash.c:147:25: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  147 |                         pg_sha1_update(&ctx->data.sha1, data, len);
      |                                         ~~~  ^
cryptohash.c:150:27: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  150 |                         pg_sha224_update(&ctx->data.sha224, data,
len);
Fixed build failure on Macbook M4
      |                                           ~~~  ^
cryptohash.c:153:27: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  153 |                         pg_sha256_update(&ctx->data.sha256, data,
len);
      |                                           ~~~  ^
cryptohash.c:156:27: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  156 |                         pg_sha384_update(&ctx->data.sha384, data,
len);
      |                                           ~~~  ^
cryptohash.c:159:27: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  159 |                         pg_sha512_update(&ctx->data.sha512, data,
len);
      |                                           ~~~  ^
cryptohash.c:185:23: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  185 |                         pg_md5_final(&ctx->data.md5, dest);
      |                                       ~~~  ^
cryptohash.c:193:24: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  193 |                         pg_sha1_final(&ctx->data.sha1, dest);
      |                                        ~~~  ^
cryptohash.c:201:26: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  201 |                         pg_sha224_final(&ctx->data.sha224, dest);
      |                                          ~~~  ^
cryptohash.c:209:26: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  209 |                         pg_sha256_final(&ctx->data.sha256, dest);
      |                                          ~~~  ^
cryptohash.c:217:26: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  217 |                         pg_sha384_final(&ctx->data.sha384, dest);
      |                                          ~~~  ^
cryptohash.c:225:26: error: no member named 'data' in 'struct
pg_cryptohash_ctx'
  225 |                         pg_sha512_final(&ctx->data.sha512, dest);
      |                                          ~~~  ^
18 errors generated.
```

With the attached fix, the build passed then, "make check" also passed.

Chao Li (Evan)
---------------------
HighGo Software Co., Ltd.
https://www.highgo.com/

---

From: Ashutosh Bapat <[email-masked]>
Date: Tue, 30 Sep 2025 16:51:51 +0530

On Wed, Sep 24, 2025 at 4:49 AM Chao Li <[email-masked]> wrote:
>
>
> On Tue, Sep 23, 2025 at 5:38 PM Peter Eisentraut <[email-masked]> wrote:
>>
>>
>>
> But when I tried to build on my Macbook M4, it got 18 errors against cryptohash.c:
> ```
> cryptohash.c:108:22: error: no member named 'data' in 'struct pg_cryptohash_ctx'
... snip ...
> cryptohash.c:225:26: error: no member named 'data' in 'struct pg_cryptohash_ctx'

I am using meson and gcc with following versions

$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ meson --version
0.61.2

I am getting opposite of those errors

../../coderoot/pg/src/common/cryptohash.c: In function ‘pg_cryptohash_init’:
../../coderoot/pg/src/common/cryptohash.c:108:41: error:
‘pg_cryptohash_ctx’ has no member named ‘md5’
  108 |                         pg_md5_init(&ctx->md5);
      |                                         ^~
... snip ...
../../coderoot/pg/src/common/cryptohash.c:225:45: error:
‘pg_cryptohash_ctx’ has no member named ‘sha512’
  225 |                         pg_sha512_final(&ctx->sha512, dest);

Attached patch fixes those errors for me.

-- 
Best Wishes,
Ashutosh Bapat
index fc0555d2f99..e8a35c2ec35 100644
 
 /*

---

From: Álvaro Herrera <[email-masked]>
Date: Tue, 30 Sep 2025 13:44:00 +0200

> @@ -61,7 +61,7 @@ struct pg_cryptohash_ctx

Isn't this patch 0015 in Peter's series?

-- 
Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
"Saca el libro que tu religión considere como el indicado para encontrar la
oración que traiga paz a tu alma. Luego rebootea el computador
y ve si funciona" (Carlos Duclós)

---

From: Ashutosh Bapat <[email-masked]>
Date: Tue, 30 Sep 2025 20:11:08 +0530

> Isn't this patch 0015 in Peter's series?

I found the compilation errors after pulling the latest sources at
that time. I thought the patch series is committed and hence this
report and patch. Didn't look at the patch series.

But the problematic commit has been reverted since then.

-- 
Best Wishes,
Ashutosh Bapat

---

From: Álvaro Herrera <[email-masked]>
Date: Tue, 30 Sep 2025 16:50:52 +0200

> report and patch. Didn't look at the patch series.

Ah, okay.

-- 
Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/

---

From: Peter Eisentraut <[email-masked]>
Date: Fri, 3 Oct 2025 09:01:26 +0200

> I would have used this in the DSM registry if it was available.  Patch

This looks good to me, and also mostly harmless in terms of backpatching.

---

From: Nathan Bossart <[email-masked]>
Date: Fri, 3 Oct 2025 10:16:11 -0500

> This looks good to me, and also mostly harmless in terms of backpatching.

Committed, thanks for reviewing.

-- 
nathan

---

From: Jacob Champion <[email-masked]>
Date: Thu, 16 Oct 2025 10:40:10 -0700

> I would have used this in the DSM registry if it was available.  Patch

Likewise for libpq-oauth, as attached.

Thanks,
--Jacob

---

From: Nathan Bossart <[email-masked]>
Date: Fri, 17 Oct 2025 09:23:15 -0500

> Likewise for libpq-oauth, as attached.

LGTM

-- 
nathan

---

From: Jacob Champion <[email-masked]>
Date: Mon, 24 Nov 2025 12:27:20 -0800

> LGTM

(Pushed, thanks!)

--Jacob