Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4775dec

Browse files
author
Nikita Glukhov
committed
Shared jsonb TOAST
1 parent30683da commit4775dec

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
elseif (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
Datumtoast_values[MaxHeapAttributeNumber];
109109
Datumtoast_oldvalues[MaxHeapAttributeNumber];
110110
ToastAttrInfotoast_attr[MaxHeapAttributeNumber];
111+
AttrToastertoasters[MaxHeapAttributeNumber];
111112
ToastTupleContextttc;
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+
AttrToastertoaster=ttc.ttc_toaster[biggest_attno];
201204
Datumold_value=*p_value;
202205
Datumcompressed_value= (Datum)0;
203206
boolexternalize= 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
structvarlenatmp;
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+
Datumnew_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 */externDatumjsonb_toaster(Relationrel,Datumnew_val,
24+
Datumold_val,intmax_size,charcmethod);
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+
structvaratt_externalold_toast_ptr;
95+
structvaratt_externalnew_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+
elseif (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+
Datumnew_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+
Datumnew_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= (structvarlena*)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)

[8]ページ先頭

©2009-2025 Movatter.jp