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

Commit 4775dec

Browse files
author
Nikita Glukhov
committed
Shared jsonb TOAST
1 parent 30683da commit 4775dec

File tree

9 files changed

+937
-59
lines changed

9 files changed

+937
-59
lines changed

src/backend/access/common/heaptuple.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include "access/tupdesc_details.h"
6363
#include "executor/tuptable.h"
6464
#include "utils/expandeddatum.h"
65+
#include "utils/jsonb.h" /* FIXME */
6566

6667

6768
/* Does att's datatype allow packing into the 1-byte-header varlena format? */
@@ -269,6 +270,13 @@ fill_val(Form_pg_attribute att,
269270
data_length = VARSIZE(val);
270271
memcpy(data, val, data_length);
271272
}
273+
274+
if (!(*infomask & HEAP_HASEXTERNAL) &&
275+
att->atttypid == JSONBOID) /* FIXME */
276+
{
277+
if (JsonbHasExternal(datum))
278+
*infomask |= HEAP_HASEXTERNAL;
279+
}
272280
}
273281
else if (att->attlen == -2)
274282
{

src/backend/access/heap/heaptoast.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
108108
Datum toast_values[MaxHeapAttributeNumber];
109109
Datum toast_oldvalues[MaxHeapAttributeNumber];
110110
ToastAttrInfo toast_attr[MaxHeapAttributeNumber];
111+
AttrToaster toasters[MaxHeapAttributeNumber];
111112
ToastTupleContext ttc;
112113

113114
/*
@@ -154,6 +155,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
154155
ttc.ttc_oldisnull = toast_oldisnull;
155156
}
156157
ttc.ttc_attr = toast_attr;
158+
ttc.ttc_toaster = toasters;
157159
toast_tuple_init(&ttc);
158160

159161
/* ----------
@@ -198,6 +200,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
198200
{
199201
ToastAttrInfo *attr = &ttc.ttc_attr[biggest_attno];
200202
Datum *p_value = &ttc.ttc_values[biggest_attno];
203+
AttrToaster toaster = ttc.ttc_toaster[biggest_attno];
201204
Datum old_value = *p_value;
202205
Datum compressed_value = (Datum) 0;
203206
bool externalize = false;
@@ -208,9 +211,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
208211

209212
attr->tai_colflags &= ~TOASTCOL_NEEDS_FREE;
210213

211-
/* FIXME pass flag to check compressedSize < maxDataLen */
212-
toast_tuple_try_compression(&ttc, biggest_attno);
213-
214+
/* calculate size of other attributes */
214215
{
215216
struct varlena tmp;
216217

@@ -221,6 +222,26 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
221222
*p_value = old_value;
222223
}
223224

225+
if (toaster != NULL)
226+
{
227+
Datum new_value = toaster(ttc.ttc_rel, *p_value,
228+
(Datum) 0, maxDataLen - size,
229+
attr->tai_compression);
230+
231+
if (new_value != *p_value)
232+
{
233+
*p_value = new_value;
234+
attr->tai_size = VARSIZE(new_value);
235+
attr->tai_colflags = TOASTCOL_NEEDS_FREE;
236+
ttc.ttc_flags |= (TOAST_NEEDS_CHANGE | TOAST_NEEDS_FREE);
237+
continue;
238+
}
239+
}
240+
241+
/* FIXME pass flag to check compressedSize < maxDataLen */
242+
toast_tuple_try_compression(&ttc, biggest_attno);
243+
244+
224245
if (attr->tai_colflags & TOASTCOL_INCOMPRESSIBLE)
225246
{
226247
attr->tai_colflags |= needs_free;

src/backend/access/table/toast_helper.c

Lines changed: 87 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "access/toast_internals.h"
2121
#include "catalog/pg_type_d.h"
2222

23+
/* FIXME */ extern Datum jsonb_toaster(Relation rel, Datum new_val,
24+
Datum old_val, int max_size, char cmethod);
2325

2426
/*
2527
* Prepare to TOAST a tuple.
@@ -55,6 +57,7 @@ toast_tuple_init(ToastTupleContext *ttc)
5557
ttc->ttc_attr[i].tai_colflags = 0;
5658
ttc->ttc_attr[i].tai_oldexternal = NULL;
5759
ttc->ttc_attr[i].tai_compression = att->attcompression;
60+
ttc->ttc_toaster[i] = att->atttypid == JSONBOID ? jsonb_toaster : NULL;
5861

5962
if (ttc->ttc_oldvalues != NULL)
6063
{
@@ -70,30 +73,79 @@ toast_tuple_init(ToastTupleContext *ttc)
7073
* If the old value is stored on disk, check if it has changed so
7174
* we have to delete it later.
7275
*/
73-
if (att->attlen == -1 && !ttc->ttc_oldisnull[i] &&
74-
VARATT_IS_EXTERNAL_ONDISK(old_value))
76+
if (att->attlen == -1 && !ttc->ttc_oldisnull[i])
7577
{
76-
if (ttc->ttc_isnull[i] ||
77-
!VARATT_IS_EXTERNAL_ONDISK(new_value) ||
78-
memcmp((char *) old_value, (char *) new_value,
79-
VARSIZE_EXTERNAL(old_value)) != 0)
78+
if (VARATT_IS_EXTERNAL_ONDISK(old_value) ||
79+
VARATT_IS_EXTERNAL_ONDISK_INLINE(old_value))
8080
{
81-
/*
82-
* The old external stored value isn't needed any more
83-
* after the update
84-
*/
85-
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_DELETE_OLD;
81+
if (ttc->ttc_isnull[i] ||
82+
(!VARATT_IS_EXTERNAL_ONDISK(new_value) &&
83+
!VARATT_IS_EXTERNAL_ONDISK_INLINE(new_value)))
84+
{
85+
/*
86+
* The old external stored value isn't needed
87+
* any more after the update
88+
*/
89+
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_DELETE_OLD;
90+
ttc->ttc_flags |= TOAST_NEEDS_DELETE_OLD;
91+
}
92+
else
93+
{
94+
struct varatt_external old_toast_ptr;
95+
struct varatt_external new_toast_ptr;
96+
97+
VARATT_EXTERNAL_INLINE_GET_POINTER(old_toast_ptr, old_value);
98+
VARATT_EXTERNAL_INLINE_GET_POINTER(new_toast_ptr, new_value);
99+
100+
if (memcmp(&old_toast_ptr, &new_toast_ptr,
101+
sizeof(old_toast_ptr)) != 0)
102+
{
103+
/*
104+
* The old external stored value isn't
105+
* needed any more after the update
106+
*/
107+
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_DELETE_OLD;
108+
ttc->ttc_flags |= TOAST_NEEDS_DELETE_OLD;
109+
}
110+
else
111+
{
112+
/*
113+
* This attribute isn't changed by this
114+
* update so we reuse the original reference
115+
* to the old value in the new tuple.
116+
*/
117+
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_IGNORE;
118+
continue;
119+
}
120+
}
121+
}
122+
else if (ttc->ttc_toaster[i] &&
123+
(ttc->ttc_isnull[i] ||
124+
VARATT_IS_EXTERNAL_ONDISK(new_value) ||
125+
memcmp((char *) old_value, (char *) new_value,
126+
VARSIZE_ANY(old_value)) != 0))
127+
{
128+
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_COMPARE_OLD;
86129
ttc->ttc_flags |= TOAST_NEEDS_DELETE_OLD;
87130
}
88-
else
131+
}
132+
133+
if (ttc->ttc_toaster[i] &&
134+
(ttc->ttc_attr[i].tai_colflags & (TOASTCOL_NEEDS_DELETE_OLD |
135+
TOASTCOL_NEEDS_COMPARE_OLD)) != 0)
136+
{
137+
Datum new_val =
138+
ttc->ttc_toaster[i](ttc->ttc_rel,
139+
ttc->ttc_isnull[i] ? (Datum) 0 : ttc->ttc_values[i],
140+
ttc->ttc_oldvalues[i], -1);
141+
142+
if (new_val != (Datum) 0)
89143
{
90-
/*
91-
* This attribute isn't changed by this update so we reuse
92-
* the original reference to the old value in the new
93-
* tuple.
94-
*/
95-
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_IGNORE;
96-
continue;
144+
if (ttc->ttc_attr[i].tai_colflags & TOASTCOL_NEEDS_FREE)
145+
pfree(DatumGetPointer(ttc->ttc_values[i]));
146+
147+
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_FREE;
148+
ttc->ttc_values[i] = new_val;
97149
}
98150
}
99151
}
@@ -102,6 +154,22 @@ toast_tuple_init(ToastTupleContext *ttc)
102154
/*
103155
* For INSERT simply get the new value
104156
*/
157+
158+
if (ttc->ttc_toaster[i] && !ttc->ttc_isnull[i])
159+
{
160+
Datum new_val =
161+
ttc->ttc_toaster[i](ttc->ttc_rel, ttc->ttc_values[i], (Datum) 0, -1);
162+
163+
if (new_val != (Datum) 0)
164+
{
165+
if (ttc->ttc_attr[i].tai_colflags & TOASTCOL_NEEDS_FREE)
166+
pfree(DatumGetPointer(ttc->ttc_values[i]));
167+
168+
ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_FREE;
169+
ttc->ttc_values[i] = new_val;
170+
}
171+
}
172+
105173
new_value = (struct varlena *) DatumGetPointer(ttc->ttc_values[i]);
106174
}
107175

src/backend/utils/adt/json_generic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ JsonExpand(Json *tmp, Datum value, bool freeValue, JsonContainerOps *ops)
751751

752752
if (tmp)
753753
{
754-
Assert(0);
754+
//Assert(0);
755755
json = tmp;
756756
json->obj.isTemporary = true;
757757
}

0 commit comments

Comments
 (0)