@@ -104,6 +104,17 @@ typedef struct varatt_expanded
104104ExpandedObjectHeader * eohptr ;
105105}varatt_expanded ;
106106
107+ typedef struct varatt_extended_hdr
108+ {
109+ uint32 size ;
110+ }varatt_extended_hdr ;
111+
112+ typedef struct varatt_extended
113+ {
114+ varatt_extended_hdr hdr ;
115+ char data [FLEXIBLE_ARRAY_MEMBER ];
116+ }varatt_extended ;
117+
107118/*
108119 * Type tag for the various sorts of "TOAST pointer" datums. The peculiar
109120 * value for VARTAG_ONDISK comes from a requirement for on-disk compatibility
@@ -114,17 +125,23 @@ typedef enum vartag_external
114125VARTAG_INDIRECT = 1 ,
115126VARTAG_EXPANDED_RO = 2 ,
116127VARTAG_EXPANDED_RW = 3 ,
128+ VARTAG_EXTENDED = 4 ,
117129VARTAG_ONDISK = 18
118130}vartag_external ;
119131
120132/* this test relies on the specific tag values above */
121133#define VARTAG_IS_EXPANDED (tag ) \
122134(((tag) & ~1) == VARTAG_EXPANDED_RO)
123135
124- #define VARTAG_SIZE (tag ) \
136+ #define VARTAG_SIZE_EXTENDED (dataSize ) \
137+ (/*offsetof(varatt_extended, data) +*/ (dataSize ))
138+
139+ #define VARTAG_SIZE (tag ,ptr ) \
125140((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \
126141 VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \
127142 (tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \
143+ (tag) == VARTAG_EXTENDED ? VARTAG_SIZE_EXTENDED( \
144+ ReadUnalignedUInt32(&((varatt_extended *)(ptr))->hdr.size)) : \
128145 TrapMacro(true, "unrecognized TOAST vartag"))
129146
130147/*
@@ -232,6 +249,14 @@ typedef struct
232249#define SET_VARTAG_1B_E (PTR ,tag ) \
233250(((varattrib_1b_e *) (PTR))->va_header = 0x80, \
234251 ((varattrib_1b_e *) (PTR))->va_tag = (tag))
252+
253+ #define ReadUnalignedUInt16 (ptr ) \
254+ ((uint16)(((const uint8 *)(ptr))[1] | \
255+ (((const uint8 *)(ptr))[0] << 8)))
256+
257+ #define ReadUnalignedUInt32 (ptr ) \
258+ ((uint32)(ReadUnalignedUInt16((const uint8 *)(ptr) + 2) | \
259+ (ReadUnalignedUInt16(ptr) << 16)))
235260#else /* !WORDS_BIGENDIAN */
236261
237262#define VARATT_IS_4B (PTR ) \
@@ -264,6 +289,15 @@ typedef struct
264289#define SET_VARTAG_1B_E (PTR ,tag ) \
265290(((varattrib_1b_e *) (PTR))->va_header = 0x01, \
266291 ((varattrib_1b_e *) (PTR))->va_tag = (tag))
292+
293+ #define ReadUnalignedUInt16 (ptr ) \
294+ ((uint16)(((const uint8 *)(ptr))[0] | \
295+ (((const uint8 *)(ptr))[1] << 8)))
296+
297+ #define ReadUnalignedUInt32 (ptr ) \
298+ ((uint32)(ReadUnalignedUInt16(ptr) | \
299+ (ReadUnalignedUInt16((const uint8 *)(ptr) + 2) << 16)))
300+
267301#endif /* WORDS_BIGENDIAN */
268302
269303#define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data)
@@ -307,7 +341,9 @@ typedef struct
307341#define VARDATA_SHORT (PTR )VARDATA_1B(PTR)
308342
309343#define VARTAG_EXTERNAL (PTR )VARTAG_1B_E(PTR)
310- #define VARSIZE_EXTERNAL (PTR )(VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR)))
344+ #define VARSIZE_EXTERNAL (PTR )(VARHDRSZ_EXTERNAL + \
345+ VARTAG_SIZE(VARTAG_EXTERNAL(PTR), \
346+ VARDATA_EXTERNAL(PTR)))
311347#define VARDATA_EXTERNAL (PTR )VARDATA_1B_E(PTR)
312348
313349#define VARATT_IS_COMPRESSED (PTR )VARATT_IS_4B_C(PTR)
@@ -322,6 +358,9 @@ typedef struct
322358(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RW)
323359#define VARATT_IS_EXTERNAL_EXPANDED (PTR ) \
324360(VARATT_IS_EXTERNAL(PTR) && VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR)))
361+ #define VARATT_IS_EXTERNAL_EXTENDED (PTR ) \
362+ (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXTENDED)
363+
325364#define VARATT_IS_SHORT (PTR )VARATT_IS_1B(PTR)
326365#define VARATT_IS_EXTENDED (PTR )(!VARATT_IS_4B_U(PTR))
327366