@@ -104,6 +104,17 @@ typedef struct varatt_expanded
104
104
ExpandedObjectHeader * eohptr ;
105
105
}varatt_expanded ;
106
106
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
+
107
118
/*
108
119
* Type tag for the various sorts of "TOAST pointer" datums. The peculiar
109
120
* value for VARTAG_ONDISK comes from a requirement for on-disk compatibility
@@ -114,17 +125,23 @@ typedef enum vartag_external
114
125
VARTAG_INDIRECT = 1 ,
115
126
VARTAG_EXPANDED_RO = 2 ,
116
127
VARTAG_EXPANDED_RW = 3 ,
128
+ VARTAG_EXTENDED = 4 ,
117
129
VARTAG_ONDISK = 18
118
130
}vartag_external ;
119
131
120
132
/* this test relies on the specific tag values above */
121
133
#define VARTAG_IS_EXPANDED (tag ) \
122
134
(((tag) & ~1) == VARTAG_EXPANDED_RO)
123
135
124
- #define VARTAG_SIZE (tag ) \
136
+ #define VARTAG_SIZE_EXTENDED (dataSize ) \
137
+ (/*offsetof(varatt_extended, data) +*/ (dataSize ))
138
+
139
+ #define VARTAG_SIZE (tag ,ptr ) \
125
140
((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \
126
141
VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \
127
142
(tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \
143
+ (tag) == VARTAG_EXTENDED ? VARTAG_SIZE_EXTENDED( \
144
+ ReadUnalignedUInt32(&((varatt_extended *)(ptr))->hdr.size)) : \
128
145
TrapMacro(true, "unrecognized TOAST vartag"))
129
146
130
147
/*
@@ -232,6 +249,14 @@ typedef struct
232
249
#define SET_VARTAG_1B_E (PTR ,tag ) \
233
250
(((varattrib_1b_e *) (PTR))->va_header = 0x80, \
234
251
((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)))
235
260
#else /* !WORDS_BIGENDIAN */
236
261
237
262
#define VARATT_IS_4B (PTR ) \
@@ -264,6 +289,15 @@ typedef struct
264
289
#define SET_VARTAG_1B_E (PTR ,tag ) \
265
290
(((varattrib_1b_e *) (PTR))->va_header = 0x01, \
266
291
((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
+
267
301
#endif /* WORDS_BIGENDIAN */
268
302
269
303
#define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data)
@@ -307,7 +341,9 @@ typedef struct
307
341
#define VARDATA_SHORT (PTR )VARDATA_1B(PTR)
308
342
309
343
#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)))
311
347
#define VARDATA_EXTERNAL (PTR )VARDATA_1B_E(PTR)
312
348
313
349
#define VARATT_IS_COMPRESSED (PTR )VARATT_IS_4B_C(PTR)
@@ -322,6 +358,9 @@ typedef struct
322
358
(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RW)
323
359
#define VARATT_IS_EXTERNAL_EXPANDED (PTR ) \
324
360
(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
+
325
364
#define VARATT_IS_SHORT (PTR )VARATT_IS_1B(PTR)
326
365
#define VARATT_IS_EXTENDED (PTR )(!VARATT_IS_4B_U(PTR))
327
366