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

Commit98c5e45

Browse files
author
Nikita Glukhov
committed
WIP Free jsonb resources in user functions
1 parent4cd284e commit98c5e45

File tree

7 files changed

+146
-22
lines changed

7 files changed

+146
-22
lines changed

‎src/backend/utils/adt/jsonb.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,14 @@ jsonb_recv(PG_FUNCTION_ARGS)
141141
Datum
142142
jsonb_out(PG_FUNCTION_ARGS)
143143
{
144+
jsonbInitIterators();
145+
144146
Jsonb*jb=PG_GETARG_JSONB_P(0);
145147
char*out;
146148

147149
out=JsonToCString(JsonbRoot(jb),NULL);
148150

151+
jsonbFreeIterators();
149152
PG_FREE_IF_COPY_JSONB(jb,0);
150153

151154
PG_RETURN_CSTRING(out);
@@ -159,13 +162,17 @@ jsonb_out(PG_FUNCTION_ARGS)
159162
Datum
160163
jsonb_send(PG_FUNCTION_ARGS)
161164
{
165+
jsonbInitIterators();
166+
162167
Jsonb*jb=PG_GETARG_JSONB_P(0);
163168
StringInfoDatabuf;
164169
StringInfojtext=makeStringInfo();
165170
intversion=1;
166171

167172
(void)JsonToCString(JsonbRoot(jb),jtext);
168173

174+
jsonbFreeIterators();
175+
169176
pq_begintypsend(&buf);
170177
pq_sendint8(&buf,version);
171178
pq_sendtext(&buf,jtext->data,jtext->len);

‎src/backend/utils/adt/jsonb_op.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,18 @@ json_exists_all(PG_FUNCTION_ARGS)
149149
staticbool
150150
json_contains_internal(Json*val,Json*tmpl)
151151
{
152+
boolres;
153+
154+
jsonbInitIterators();
155+
152156
if (JB_ROOT_IS_OBJECT(val)!=JB_ROOT_IS_OBJECT(tmpl))
153-
return false;
157+
res= false;
158+
else
159+
res=JsonbDeepContains(JsonRoot(val),JsonRoot(tmpl));
154160

155-
returnJsonbDeepContains(JsonRoot(val),JsonRoot(tmpl));
161+
jsonbFreeIterators();
162+
163+
returnres;
156164
}
157165

158166
Datum

‎src/backend/utils/adt/jsonb_util.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,6 +3188,8 @@ jsonbzIteratorInit(JsonContainer *jc)
31883188
returnjsonbIteratorInit(jc,jbc,cjb);
31893189
}
31903190

3191+
List**jsonb_detoast_iterators;
3192+
31913193
staticvoid
31923194
#ifndefJSONB_DETOAST_ITERATOR
31933195
jsonbzInitFromCompresedDatum(JsonContainerData*jc,CompressedDatum*cd,JsonbContainerHeader*header)
@@ -3212,6 +3214,12 @@ jsonbzInitFromDetoastIterator(JsonContainerData *jc, DetoastIterator iter, Jsonb
32123214
cjb->iter=iter;
32133215
cjb->offset= offsetof(Jsonb,root);
32143216

3217+
#defineJSONB_FREE_ITERATORS
3218+
#ifdefJSONB_FREE_ITERATORS
3219+
if (jsonb_detoast_iterators)
3220+
*jsonb_detoast_iterators=lappend(*jsonb_detoast_iterators,iter);
3221+
#endif
3222+
32153223
if (!jsonb_partial_decompression)
32163224
PG_DETOAST_ITERATE(iter,iter->buf->capacity);
32173225
elseif (!header)
@@ -3221,14 +3229,36 @@ jsonbzInitFromDetoastIterator(JsonContainerData *jc, DetoastIterator iter, Jsonb
32213229
#endif
32223230
}
32233231

3232+
void
3233+
jsonbInitIterators(void)
3234+
{
3235+
#ifdefJSONB_FREE_ITERATORS
3236+
jsonb_detoast_iterators=palloc0(sizeof(*jsonb_detoast_iterators));
3237+
#endif
3238+
}
3239+
3240+
void
3241+
jsonbFreeIterators(void)
3242+
{
3243+
#ifdefJSONB_FREE_ITERATORS
3244+
ListCell*lc;
3245+
3246+
if (jsonb_detoast_iterators)
3247+
foreach(lc,*jsonb_detoast_iterators)
3248+
free_detoast_iterator(lfirst(lc));
3249+
3250+
jsonb_detoast_iterators=NULL;
3251+
#endif
3252+
}
3253+
32243254
staticvoid
32253255
jsonbzFree(JsonContainer*jc)
32263256
{
32273257
CompressedJsonb*cjb=jsonbzGetCompressedJsonb(jc);
32283258

32293259
#ifdefJSONB_DETOAST_ITERATOR
3230-
if (cjb->iter)
3231-
free_detoast_iterator(cjb->iter);
3260+
//if (cjb->iter)
3261+
//free_detoast_iterator(cjb->iter);
32323262
#endif
32333263
}
32343264

@@ -3825,6 +3855,8 @@ jsonb_toaster_cmp(Relation rel, JsonContainer *new_jc, JsonContainer *old_jc, ch
38253855
Datum
38263856
jsonb_toaster(Relationrel,Datumnew_val,Datumold_val,intmax_size,charcmethod)
38273857
{
3858+
jsonbInitIterators();
3859+
38283860
Json*new_js=new_val!= (Datum)0 ?DatumGetJsonbPC(new_val,NULL, false) :NULL;
38293861
Json*old_js=old_val!= (Datum)0 ?DatumGetJsonbPC(old_val,NULL, false) :NULL;
38303862
Datumres= (Datum)0;
@@ -3852,6 +3884,8 @@ jsonb_toaster(Relation rel, Datum new_val, Datum old_val, int max_size, char cme
38523884
jsonb_toaster_delete_recursive(rel,JsonRoot(old_js), false);
38533885
}
38543886

3887+
jsonbFreeIterators();
3888+
38553889
returnres;
38563890
}
38573891

‎src/backend/utils/adt/jsonfuncs.c

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,8 @@ json_object_field_internal(Json *jb, text *key)
634634
Datum
635635
jsonb_object_field(PG_FUNCTION_ARGS)
636636
{
637+
jsonbInitIterators();
638+
637639
Jsonb*jb=PG_GETARG_JSONB_P(0);
638640
JsonValue*res=json_object_field_internal(jb,
639641
PG_GETARG_TEXT_PP(1));
@@ -644,11 +646,13 @@ jsonb_object_field(PG_FUNCTION_ARGS)
644646

645647
//if (res && res->type == jbvBinary)
646648
//JsonContainerFree(res->val.binary.data);
649+
jsonbFreeIterators();
647650
PG_FREE_IF_COPY_JSONB(jb,0);
648651
PG_RETURN_DATUM(r);
649652
}
650653
else
651654
{
655+
jsonbFreeIterators();
652656
PG_FREE_IF_COPY_JSONB(jb,0);
653657
PG_RETURN_NULL();
654658
}
@@ -669,6 +673,8 @@ json_object_field(PG_FUNCTION_ARGS)
669673
Datum
670674
jsonb_object_field_text(PG_FUNCTION_ARGS)
671675
{
676+
jsonbInitIterators();
677+
672678
Jsonb*jb=PG_GETARG_JSONB_P(0);
673679
JsonValue*res=json_object_field_internal(jb,PG_GETARG_TEXT_PP(1));
674680

@@ -678,11 +684,13 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
678684

679685
//if (res && res->type == jbvBinary)
680686
//JsonContainerFree(res->val.binary.data);
687+
jsonbFreeIterators();
681688
PG_FREE_IF_COPY_JSONB(jb,0);
682689
PG_RETURN_TEXT_P(r);
683690
}
684691
else
685692
{
693+
jsonbFreeIterators();
686694
PG_FREE_IF_COPY_JSONB(jb,0);
687695
PG_RETURN_NULL();
688696
}
@@ -726,11 +734,17 @@ json_array_element_internal(Json *jb, int element)
726734
Datum
727735
jsonb_array_element(PG_FUNCTION_ARGS)
728736
{
729-
JsonValue*res=json_array_element_internal(PG_GETARG_JSONB_P(0),
737+
jsonbInitIterators();
738+
739+
JsonValue*res=json_array_element_internal(PG_GETARG_JSONB_PC(0),
730740
PG_GETARG_INT32(1));
731741

742+
Datumr=res ?JsonValueGetJsonbDatum(res) : (Datum)0;
743+
744+
jsonbFreeIterators();
745+
732746
if (res)
733-
PG_RETURN_JSONB_P(JsonbValueToJsonb(res));
747+
PG_RETURN_DATUM(r);
734748
else
735749
PG_RETURN_NULL();
736750
}
@@ -750,11 +764,15 @@ json_array_element(PG_FUNCTION_ARGS)
750764
Datum
751765
jsonb_array_element_text(PG_FUNCTION_ARGS)
752766
{
753-
JsonValue*res=json_array_element_internal(PG_GETARG_JSONB_P(0),
767+
jsonbInitIterators();
768+
JsonValue*res=json_array_element_internal(PG_GETARG_JSONB_PC(0),
754769
PG_GETARG_INT32(1));
770+
text*r=res&&res->type ?JsonbValueAsText(res) :NULL;
755771

756-
if (res&&res->type!=jbvNull)
757-
PG_RETURN_TEXT_P(JsonbValueAsText(res));
772+
jsonbFreeIterators();
773+
774+
if (r)
775+
PG_RETURN_TEXT_P(r);
758776
else
759777
PG_RETURN_NULL();
760778
}
@@ -1168,7 +1186,13 @@ jsonb_each(PG_FUNCTION_ARGS)
11681186
Datum
11691187
jsonb_each_text(PG_FUNCTION_ARGS)
11701188
{
1171-
returneach_worker_json(fcinfo,"jsonb_each_text", true, true);
1189+
Datumres;
1190+
1191+
jsonbInitIterators();
1192+
res=each_worker_json(fcinfo,"jsonb_each_text", true, true);
1193+
jsonbFreeIterators();
1194+
1195+
returnres;
11721196
}
11731197

11741198
Datum
@@ -1318,7 +1342,13 @@ jsonb_array_elements(PG_FUNCTION_ARGS)
13181342
Datum
13191343
jsonb_array_elements_text(PG_FUNCTION_ARGS)
13201344
{
1321-
returnelements_worker_json(fcinfo,"jsonb_array_elements_text", true, true);
1345+
Datumres;
1346+
1347+
jsonbInitIterators();
1348+
res=elements_worker_json(fcinfo,"jsonb_array_elements_text", true, true);
1349+
jsonbFreeIterators();
1350+
1351+
PG_RETURN_DATUM(res);
13221352
}
13231353

13241354
Datum
@@ -2810,7 +2840,7 @@ json_concat_internal(Json *jb1, Json *jb2, bool is_jsonb)
28102840

28112841
Assert(res!=NULL);
28122842

2813-
returnJsonbValueToJsonb(res);
2843+
returnJsonValueToJson(res);
28142844
}
28152845

28162846
/*
@@ -2821,17 +2851,35 @@ json_concat_internal(Json *jb1, Json *jb2, bool is_jsonb)
28212851
Datum
28222852
jsonb_concat(PG_FUNCTION_ARGS)
28232853
{
2824-
PG_RETURN_JSONB_P(json_concat_internal(PG_GETARG_JSONB_P(0),
2825-
PG_GETARG_JSONB_P(1),
2826-
true));
2854+
jsonbInitIterators();
2855+
2856+
Json*js1=PG_GETARG_JSONB_P(0);
2857+
Json*js2=PG_GETARG_JSONB_P(1);
2858+
Json*js=json_concat_internal(js1,js2, true);
2859+
Datumres=JsonbPGetDatum(js);//JsonValueGetJsonbDatum(res);
2860+
2861+
jsonbFreeIterators();
2862+
PG_FREE_IF_COPY_JSONB(js1,0);
2863+
PG_FREE_IF_COPY_JSONB(js2,0);
2864+
2865+
PG_RETURN_DATUM(res);
28272866
}
28282867

28292868
Datum
28302869
json_concat(PG_FUNCTION_ARGS)
28312870
{
2832-
PG_RETURN_JSONT_P(json_concat_internal(PG_GETARG_JSONT_P(0),
2833-
PG_GETARG_JSONT_P(1),
2834-
false));
2871+
jsonbInitIterators();
2872+
2873+
Json*js1=PG_GETARG_JSONT_P(0);
2874+
Json*js2=PG_GETARG_JSONT_P(1);
2875+
Json*js=json_concat_internal(js1,js2, false);
2876+
Datumres=JsontPGetDatum(js);
2877+
2878+
jsonbFreeIterators();
2879+
PG_FREE_IF_COPY_JSONB(js1,0);
2880+
PG_FREE_IF_COPY_JSONB(js2,0);
2881+
2882+
PG_RETURN_DATUM(res);
28352883
}
28362884

28372885
staticJson*
@@ -3139,10 +3187,21 @@ json_set_internal(Json *in, ArrayType *path, Json *newjsonb, bool create)
31393187
Datum
31403188
jsonb_set(PG_FUNCTION_ARGS)
31413189
{
3142-
PG_RETURN_JSONB_P(json_set_internal(PG_GETARG_JSONB_P(0),
3190+
jsonbInitIterators();
3191+
3192+
Json*jb1=PG_GETARG_JSONB_P(0);
3193+
Json*jb2=PG_GETARG_JSONB_P(2);
3194+
Json*res=json_set_internal(jb1,
31433195
PG_GETARG_ARRAYTYPE_P(1),
3144-
PG_GETARG_JSONB_P(2),
3145-
PG_GETARG_BOOL(3)));
3196+
jb2,
3197+
PG_GETARG_BOOL(3));
3198+
Datumr=JsonbPGetDatum(res);
3199+
3200+
jsonbFreeIterators();
3201+
PG_FREE_IF_COPY_JSONB(jb1,0);
3202+
PG_FREE_IF_COPY_JSONB(jb2,2);
3203+
3204+
PG_RETURN_DATUM(r);
31463205
}
31473206

31483207
Datum

‎src/backend/utils/adt/jsonpath_exec.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,8 @@ jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz, bool is_jsonb)
459459
funcctx=SRF_FIRSTCALL_INIT();
460460
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
461461

462+
jsonbInitIterators();
463+
462464
jb=is_jsonb ?PG_GETARG_JSONB_P_COPY(0) :PG_GETARG_JSONT_P_COPY(0);
463465
jp=PG_GETARG_JSONPATH_P_COPY(1);
464466
vars=is_jsonb ?PG_GETARG_JSONB_P_COPY(2) :PG_GETARG_JSONT_P_COPY(2);
@@ -477,7 +479,10 @@ jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz, bool is_jsonb)
477479
c=list_head(found);
478480

479481
if (c==NULL)
482+
{
483+
jsonbFreeIterators();
480484
SRF_RETURN_DONE(funcctx);
485+
}
481486

482487
v=lfirst(c);
483488
funcctx->user_fctx=list_delete_first(found);
@@ -490,7 +495,11 @@ jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz, bool is_jsonb)
490495
Datum
491496
jsonb_path_query(PG_FUNCTION_ARGS)
492497
{
493-
returnjsonb_path_query_internal(fcinfo, false, true);
498+
Datumres;
499+
500+
res=jsonb_path_query_internal(fcinfo, false, true);
501+
502+
returnres;
494503
}
495504

496505
Datum

‎src/include/access/detoast.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,12 @@ detoast_iterate(DetoastIterator detoast_iter, const char *destend)
216216
if (detoast_iter->buf->limit==detoast_iter->buf->capacity)
217217
{
218218
detoast_iter->done= true;
219+
#if0
220+
if (detoast_iter->buf==fetch_iter->buf)
221+
fetch_iter->buf=NULL;
219222
free_fetch_datum_iterator(fetch_iter);
220223
detoast_iter->fetch_datum_iterator=NULL;
224+
#endif
221225
}
222226
}
223227

‎src/include/utils/jsonb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,4 +437,7 @@ extern Datum jsonb_toaster(Relation rel, Datum new_val, Datum old_val,
437437
intmax_size,charcmethod);/* FIXME */
438438
externboolJsonbHasExternal(Datumjb);
439439

440+
externvoidjsonbInitIterators(void);
441+
externvoidjsonbFreeIterators(void);
442+
440443
#endif/* __JSONB_H__ */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp