31
31
#include "miscadmin.h"
32
32
#include "utils/expandeddatum.h"
33
33
#include "utils/fmgroids.h"
34
+ #include "utils/memutils.h"
34
35
#include "utils/rel.h"
35
36
#include "utils/snapmgr.h"
36
37
#include "utils/jsonb.h"
37
38
38
- typedef struct varatt_external_diff
39
- {
40
- int32 va_diff_offset ;
41
- char va_diff_data [FLEXIBLE_ARRAY_MEMBER ];
42
- } varatt_external_diff ;
43
-
44
39
char *
45
40
jsonxWriteCustomToastPointerHeader (char * ptr , Oid toasterid , uint32 header ,
46
41
int datalen , int rawsize )
@@ -53,6 +48,14 @@ jsonxWriteCustomToastPointerHeader(char *ptr, Oid toasterid, uint32 header,
53
48
54
49
VARATT_CUSTOM_SET_TOASTERID (ptr , toasterid );
55
50
VARATT_CUSTOM_SET_DATA_RAW_SIZE (ptr , rawsize );
51
+
52
+ if (size - hdrsize > VARATT_CUSTOM_MAX_DATA_SIZE )
53
+ ereport (ERROR ,
54
+ (errcode (ERRCODE_PROGRAM_LIMIT_EXCEEDED ),
55
+ errmsg ("atribute length too large" )));
56
+ //elog(ERROR, "custom TOAST pointer data size exceeds maximal size: %d > %d",
57
+ // (int)(size - hdrsize), VARATT_CUSTOM_MAX_DATA_SIZE);
58
+
56
59
VARATT_CUSTOM_SET_DATA_SIZE (ptr , size - hdrsize );
57
60
58
61
if (aligned_hdrsize != hdrsize )
@@ -135,15 +138,41 @@ jsonx_toast_make_pointer_compressed_chunks(Oid toasterid,
135
138
return custom_ptr ;
136
139
}
137
140
141
+ struct varlena *
142
+ jsonx_toast_make_pointer_diff (Oid toasterid ,
143
+ struct varatt_external * toast_pointer ,
144
+ int32 diff_offset , int32 diff_len ,
145
+ const void * diff_data )
146
+ {
147
+ JsonxPointerDiff * diff ;
148
+ char * data ;
149
+ int datalen =
150
+ TOAST_POINTER_SIZE + offsetof(JsonxPointerDiff , data ) + diff_len ;
151
+
152
+ struct varlena * result =
153
+ jsonx_toast_make_custom_pointer (toasterid , JSONX_POINTER_DIFF ,
154
+ datalen , toast_pointer -> va_rawsize , & data );
155
+
156
+ SET_VARTAG_EXTERNAL (data , VARTAG_ONDISK );
157
+ memcpy (VARDATA_EXTERNAL (data ), toast_pointer , sizeof (* toast_pointer ));
158
+
159
+ diff = (JsonxPointerDiff * )(data + TOAST_POINTER_SIZE );
160
+ memcpy (& diff -> offset , & diff_offset , sizeof (diff_offset ));
161
+ memcpy (diff -> data , diff_data , diff_len );
162
+
163
+ return result ;
164
+ }
165
+
138
166
struct varlena *
139
167
jsonxMakeToastPointer (JsonbToastedContainerPointerData * ptr )
140
168
{
141
- if (ptr -> ntids )
169
+ if (ptr -> ntids || ptr -> has_diff )
142
170
{
143
171
char * data ;
144
- uint32 header = ptr -> ntids | (ptr -> compressed_tids ?
145
- JSONX_POINTER_DIRECT_TIDS_COMP :
146
- JSONX_POINTER_DIRECT_TIDS );
172
+ uint32 header = ptr -> has_diff ? JSONX_POINTER_DIFF :
173
+ ptr -> ntids | (ptr -> compressed_tids ?
174
+ JSONX_POINTER_DIRECT_TIDS_COMP :
175
+ JSONX_POINTER_DIRECT_TIDS );
147
176
struct varlena * custom_ptr =
148
177
jsonx_toast_make_custom_pointer (ptr -> toasterid , header ,
149
178
TOAST_POINTER_SIZE + ptr -> tail_size ,
@@ -175,14 +204,17 @@ jsonxMakeToastPointer(JsonbToastedContainerPointerData *ptr)
175
204
void
176
205
jsonxWriteToastPointer (StringInfo buffer , JsonbToastedContainerPointerData * ptr )
177
206
{
178
- if (ptr -> ntids )
207
+ if (ptr -> ntids || ptr -> has_diff )
179
208
{
180
209
char custom_ptr [JSONX_CUSTOM_PTR_HEADER_SIZE ];
181
210
char toast_ptr [TOAST_POINTER_SIZE ];
182
- uint32 header = ptr -> ntids | (ptr -> compressed_tids ?
183
- JSONX_POINTER_DIRECT_TIDS_COMP :
184
- JSONX_POINTER_DIRECT_TIDS );
211
+ uint32 header = ptr -> has_diff ?
212
+ JSONX_POINTER_DIFF :
213
+ ptr -> ntids | (ptr -> compressed_tids ?
214
+ JSONX_POINTER_DIRECT_TIDS_COMP :
215
+ JSONX_POINTER_DIRECT_TIDS );
185
216
217
+ Assert (ptr -> has_diff ^ ptr -> ntids );
186
218
Assert (!ptr -> compressed_chunks );
187
219
188
220
jsonxWriteCustomToastPointerHeader (custom_ptr , ptr -> toasterid , header ,
@@ -241,6 +273,7 @@ jsonxInitToastedContainerPointer(JsonbToastedContainerPointerData *jbcptr,
241
273
jbcptr -> ntids = ntids ;
242
274
jbcptr -> compressed_tids = compressed_tids ;
243
275
jbcptr -> compressed_chunks = compressed_chunks ;
276
+ jbcptr -> has_diff = false;
244
277
jbcptr -> toasterid = toasterid ;
245
278
jbcptr -> container_offset = container_offset ;
246
279
}
@@ -1611,13 +1644,13 @@ jsonx_create_detoast_iterator(struct varlena *attr)
1611
1644
1612
1645
if (type == JSONX_POINTER_DIFF )
1613
1646
{
1614
- varatt_external_diff * diff = (varatt_external_diff * ) inline_data ;
1647
+ JsonxPointerDiff * diff = (JsonxPointerDiff * ) inline_data ;
1615
1648
1616
1649
iter -> diff .inline_data = inline_data ;
1617
1650
iter -> diff .inline_size = inline_size ;
1618
- iter -> diff .size = inline_size - offsetof(varatt_external_diff , va_diff_data );
1619
- iter -> diff .offset = diff -> va_diff_offset ;
1620
- iter -> diff .data = diff -> va_diff_data ; /* FIXME MemoryContext */
1651
+ iter -> diff .size = inline_size - offsetof(JsonxPointerDiff , data );
1652
+ iter -> diff .offset = diff -> offset ;
1653
+ iter -> diff .data = diff -> data ; /* FIXME MemoryContext */
1621
1654
}
1622
1655
1623
1656
return iter ;
@@ -1726,12 +1759,12 @@ toast_apply_diff(struct varlena *attr, struct varlena *result,
1726
1759
if (VARATT_IS_EXTERNAL_ONDISK_INLINE_DIFF (attr ))
1727
1760
{
1728
1761
struct varatt_external_versioned toast_pointer ;
1729
- struct varatt_external_diff diff ;
1762
+ struct JsonxPointerDiff diff ;
1730
1763
const char * inline_data = VARDATA_EXTERNAL_INLINE (attr );
1731
1764
/* Must copy to access aligned fields */
1732
1765
int32 inline_size = VARATT_EXTERNAL_INLINE_GET_POINTER (toast_pointer , attr );
1733
1766
int32 attrsize = VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer .va_external );
1734
- Size data_offset = offsetof(varatt_external_diff , va_diff_data );
1767
+ Size data_offset = offsetof(JsonxPointerDiff , data );
1735
1768
Size diff_size = inline_size - data_offset ;
1736
1769
const char * diff_data = inline_data + data_offset ;
1737
1770
@@ -1741,7 +1774,7 @@ toast_apply_diff(struct varlena *attr, struct varlena *result,
1741
1774
slicelength = attrsize - sliceoffset ;
1742
1775
1743
1776
toast_apply_diff_internal (result , diff_data ,
1744
- diff .va_diff_offset , diff_size ,
1777
+ diff .offset , diff_size ,
1745
1778
sliceoffset , slicelength );
1746
1779
}
1747
1780
}
0 commit comments