Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 412eb4e

Browse files
author
Nikita Glukhov
committed
TMP: in-place updates
1 parent b210613 commit 412eb4e

File tree

12 files changed

+645
-137
lines changed

12 files changed

+645
-137
lines changed

contrib/jsonb_toaster/expected/jsonb_toaster.out

+117
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,120 @@ SELECT id, key, pg_column_size(value::text) FROM test_jsonb_toaster, jsonb_each(
123123
(100 rows)
124124

125125
DROP TABLE test_jsonb_toaster;
126+
create table test_jsonbz_arr (id int, js jsonb toaster jsonb_toaster);
127+
insert into test_jsonbz_arr
128+
select
129+
j id,
130+
jsonb_build_object(
131+
'a', jsonb_agg(repeat('a', pow(2, 6 + i)::int)),
132+
'b', 'foo'
133+
) js
134+
from
135+
generate_series(0, 19) j,
136+
generate_series(0, j) i
137+
group by j
138+
order by j;
139+
update test_jsonbz_arr set js = jsonb_set(js, '{a,0}', to_jsonb(repeat('b', 64)));
140+
select id, js->'a'->>0 from test_jsonbz_arr order by id;
141+
id | ?column?
142+
----+------------------------------------------------------------------
143+
0 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
144+
1 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
145+
2 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
146+
3 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
147+
4 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
148+
5 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
149+
6 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
150+
7 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
151+
8 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
152+
9 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
153+
10 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
154+
11 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
155+
12 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
156+
13 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
157+
14 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
158+
15 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
159+
16 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
160+
17 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
161+
18 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
162+
19 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
163+
(20 rows)
164+
165+
update test_jsonbz_arr set js = jsonb_set(js, '{a,0}', to_jsonb(repeat('c', 64)));
166+
select id, js->'a'->>0 from test_jsonbz_arr order by id;
167+
id | ?column?
168+
----+------------------------------------------------------------------
169+
0 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
170+
1 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
171+
2 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
172+
3 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
173+
4 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
174+
5 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
175+
6 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
176+
7 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
177+
8 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
178+
9 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
179+
10 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
180+
11 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
181+
12 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
182+
13 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
183+
14 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
184+
15 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
185+
16 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
186+
17 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
187+
18 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
188+
19 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
189+
(20 rows)
190+
191+
update test_jsonbz_arr set js = jsonb_set(js, '{a,0}', to_jsonb(repeat('d', 65)));
192+
select id, js->'a'->>0 from test_jsonbz_arr order by id;
193+
id | ?column?
194+
----+-------------------------------------------------------------------
195+
0 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
196+
1 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
197+
2 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
198+
3 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
199+
4 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
200+
5 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
201+
6 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
202+
7 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
203+
8 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
204+
9 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
205+
10 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
206+
11 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
207+
12 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
208+
13 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
209+
14 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
210+
15 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
211+
16 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
212+
17 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
213+
18 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
214+
19 | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
215+
(20 rows)
216+
217+
update test_jsonbz_arr set js = jsonb_set(js, '{a,0}', to_jsonb(repeat('e', 65)));
218+
select id, js->'a'->>0 from test_jsonbz_arr order by id;
219+
id | ?column?
220+
----+-------------------------------------------------------------------
221+
0 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
222+
1 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
223+
2 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
224+
3 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
225+
4 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
226+
5 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
227+
6 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
228+
7 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
229+
8 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
230+
9 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
231+
10 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
232+
11 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
233+
12 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
234+
13 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
235+
14 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
236+
15 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
237+
16 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
238+
17 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
239+
18 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
240+
19 | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
241+
(20 rows)
242+

contrib/jsonb_toaster/jsonb_toast_internals.c

+54-21
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,11 @@
3131
#include "miscadmin.h"
3232
#include "utils/expandeddatum.h"
3333
#include "utils/fmgroids.h"
34+
#include "utils/memutils.h"
3435
#include "utils/rel.h"
3536
#include "utils/snapmgr.h"
3637
#include "utils/jsonb.h"
3738

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-
4439
char *
4540
jsonxWriteCustomToastPointerHeader(char *ptr, Oid toasterid, uint32 header,
4641
int datalen, int rawsize)
@@ -53,6 +48,14 @@ jsonxWriteCustomToastPointerHeader(char *ptr, Oid toasterid, uint32 header,
5348

5449
VARATT_CUSTOM_SET_TOASTERID(ptr, toasterid);
5550
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+
5659
VARATT_CUSTOM_SET_DATA_SIZE(ptr, size - hdrsize);
5760

5861
if (aligned_hdrsize != hdrsize)
@@ -135,15 +138,41 @@ jsonx_toast_make_pointer_compressed_chunks(Oid toasterid,
135138
return custom_ptr;
136139
}
137140

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+
138166
struct varlena *
139167
jsonxMakeToastPointer(JsonbToastedContainerPointerData *ptr)
140168
{
141-
if (ptr->ntids)
169+
if (ptr->ntids || ptr->has_diff)
142170
{
143171
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);
147176
struct varlena *custom_ptr =
148177
jsonx_toast_make_custom_pointer(ptr->toasterid, header,
149178
TOAST_POINTER_SIZE + ptr->tail_size,
@@ -175,14 +204,17 @@ jsonxMakeToastPointer(JsonbToastedContainerPointerData *ptr)
175204
void
176205
jsonxWriteToastPointer(StringInfo buffer, JsonbToastedContainerPointerData *ptr)
177206
{
178-
if (ptr->ntids)
207+
if (ptr->ntids || ptr->has_diff)
179208
{
180209
char custom_ptr[JSONX_CUSTOM_PTR_HEADER_SIZE];
181210
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);
185216

217+
Assert(ptr->has_diff ^ ptr->ntids);
186218
Assert(!ptr->compressed_chunks);
187219

188220
jsonxWriteCustomToastPointerHeader(custom_ptr, ptr->toasterid, header,
@@ -241,6 +273,7 @@ jsonxInitToastedContainerPointer(JsonbToastedContainerPointerData *jbcptr,
241273
jbcptr->ntids = ntids;
242274
jbcptr->compressed_tids = compressed_tids;
243275
jbcptr->compressed_chunks = compressed_chunks;
276+
jbcptr->has_diff = false;
244277
jbcptr->toasterid = toasterid;
245278
jbcptr->container_offset = container_offset;
246279
}
@@ -1611,13 +1644,13 @@ jsonx_create_detoast_iterator(struct varlena *attr)
16111644

16121645
if (type == JSONX_POINTER_DIFF)
16131646
{
1614-
varatt_external_diff *diff = (varatt_external_diff *) inline_data;
1647+
JsonxPointerDiff *diff = (JsonxPointerDiff *) inline_data;
16151648

16161649
iter->diff.inline_data = inline_data;
16171650
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 */
16211654
}
16221655

16231656
return iter;
@@ -1726,12 +1759,12 @@ toast_apply_diff(struct varlena *attr, struct varlena *result,
17261759
if (VARATT_IS_EXTERNAL_ONDISK_INLINE_DIFF(attr))
17271760
{
17281761
struct varatt_external_versioned toast_pointer;
1729-
struct varatt_external_diff diff;
1762+
struct JsonxPointerDiff diff;
17301763
const char *inline_data = VARDATA_EXTERNAL_INLINE(attr);
17311764
/* Must copy to access aligned fields */
17321765
int32 inline_size = VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer, attr);
17331766
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);
17351768
Size diff_size = inline_size - data_offset;
17361769
const char *diff_data = inline_data + data_offset;
17371770

@@ -1741,7 +1774,7 @@ toast_apply_diff(struct varlena *attr, struct varlena *result,
17411774
slicelength = attrsize - sliceoffset;
17421775

17431776
toast_apply_diff_internal(result, diff_data,
1744-
diff.va_diff_offset, diff_size,
1777+
diff.offset, diff_size,
17451778
sliceoffset, slicelength);
17461779
}
17471780
}

0 commit comments

Comments
 (0)