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

Commit44c3c08

Browse files
author
Nikita Glukhov
committed
Add temporary stack-allocated expanded Jsons
1 parent97969a6 commit44c3c08

File tree

7 files changed

+163
-62
lines changed

7 files changed

+163
-62
lines changed

‎src/backend/tsearch/to_tsany.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
280280

281281
iterate_jsonb_string_values(jb,&state, (JsonIterateStringValuesAction)add_to_tsvector);
282282

283-
PG_FREE_IF_COPY(jb,1);
283+
PG_FREE_IF_COPY_JSONB(jb,1);
284284

285285
if (state.result==NULL)
286286
{
@@ -329,11 +329,12 @@ json_to_tsvector_byid(PG_FUNCTION_ARGS)
329329

330330
#ifndefJSON_GENERIC
331331
iterate_json_string_values(json,&state, (JsonIterateStringValuesAction)add_to_tsvector);
332+
PG_FREE_IF_COPY(json,1);
332333
#else
333334
iterate_jsonb_string_values(json,&state, (JsonIterateStringValuesAction)add_to_tsvector);
335+
PG_FREE_IF_COPY_JSONB(json,1);
334336
#endif
335337

336-
PG_FREE_IF_COPY(json,1);
337338
if (state.result==NULL)
338339
{
339340
/* There weren't any string elements in json,

‎src/backend/tsearch/wparser.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
412412
/* flatten result to jsonb before jb freeing */
413413
out=DatumGetJsonb(PointerGetDatum(JsonValueToJsonb(JsonToJsonValue(out,&jv))));
414414

415-
PG_FREE_IF_COPY(jb,1);
415+
PG_FREE_IF_COPY_JSONB(jb,1);
416416
PG_FREE_IF_COPY(query,2);
417417
if (opt)
418418
PG_FREE_IF_COPY(opt,3);
@@ -492,6 +492,7 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
492492

493493
#ifndefJSON_GENERIC
494494
out=transform_json_string_values(json,state,action);
495+
PG_FREE_IF_COPY(json,1);
495496
#else
496497
{
497498
Jsonb*jsonb=transform_jsonb_string_values(json,state,action);
@@ -500,10 +501,11 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
500501
out=cstring_to_text(str);
501502

502503
pfree(str);
504+
505+
PG_FREE_IF_COPY_JSONB(json,1);
503506
}
504507
#endif
505508

506-
PG_FREE_IF_COPY(json,1);
507509
PG_FREE_IF_COPY(query,2);
508510
if (opt)
509511
PG_FREE_IF_COPY(opt,3);

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515
#include"postgres.h"
1616

17+
#include"utils/datum.h"
1718
#include"utils/expandeddatum.h"
1819
#include"utils/memutils.h"
1920

@@ -122,6 +123,9 @@ TransferExpandedObject(Datum d, MemoryContext new_parent)
122123
/* Assert caller gave a R/W pointer */
123124
Assert(VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)));
124125

126+
if (!eohptr->eoh_context)
127+
returndatumCopy(d, false,-1);
128+
125129
/* Transfer ownership */
126130
MemoryContextSetParent(eohptr->eoh_context,new_parent);
127131

@@ -141,5 +145,8 @@ DeleteExpandedObject(Datum d)
141145
Assert(VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)));
142146

143147
/* Kill it */
144-
MemoryContextDelete(eohptr->eoh_context);
148+
if (eohptr->eoh_context)
149+
MemoryContextDelete(eohptr->eoh_context);
150+
else
151+
pfree(eohptr);
145152
}

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

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
#include"utils/json_generic.h"
1414
#include"utils/memutils.h"
1515

16-
staticJson*JsonExpand(Datumvalue,JsonContainerOps*ops,
17-
CompressionOptionsopts);
16+
staticJson*JsonExpand(Json*tmp,Datumvalue,boolfreeValue,
17+
JsonContainerOps*ops,CompressionOptionsoptions);
1818

1919
staticJsonContainerOpsjsonvContainerOps;
2020

@@ -619,8 +619,7 @@ jsonWriteExtended(JsonContainer *jc, void *ptr, Size allocated_size)
619619
}
620620

621621
staticJson*
622-
JsonInitExtended(conststructvarlena*toasted,
623-
conststructvarlena*detoasted)
622+
JsonInitExtended(Json*tmp,structvarlena*extvalue,boolfreeValue)
624623
{
625624
JsonContainerOps*ops;
626625
CompressionMethodRoutine*cmr;
@@ -633,9 +632,9 @@ JsonInitExtended(const struct varlena *toasted,
633632
Size (*decodeOptions)(constvoid*buf,
634633
CompressionOptions*options);
635634

636-
Assert(VARATT_IS_EXTERNAL_EXTENDED(detoasted));
635+
Assert(VARATT_IS_EXTERNAL_EXTENDED(extvalue));
637636

638-
pextjs= (varatt_extended_json*)VARDATA_EXTERNAL(detoasted);
637+
pextjs= (varatt_extended_json*)VARDATA_EXTERNAL(extvalue);
639638
memcpy(&extjs,pextjs, offsetof(varatt_extended_json,data));
640639

641640
totalSize=extjs.vaext.size- offsetof(varatt_extended_json,data);
@@ -667,8 +666,11 @@ JsonInitExtended(const struct varlena *toasted,
667666
&pextjs->data[optionsSize],
668667
totalSize-optionsSize));
669668

669+
if (freeValue)
670+
pfree(extvalue);
671+
670672
if (ops)
671-
returnJsonExpand(value,ops,options);
673+
returnJsonExpand(tmp,value, true,ops,options);
672674

673675
value=cmr->decompress(value,options);
674676

@@ -681,19 +683,19 @@ JsonInitExtended(const struct varlena *toasted,
681683
staticvoid
682684
JsonInit(Json*json)
683685
{
684-
constvoid*data=DatumGetPointer(json->obj.compressed);
686+
constvoid*data=DatumGetPointer(json->obj.value);
687+
constvoid*detoasted_data;
685688

686689
Assert(json->root.data||data);
687690

688691
if (json->root.data|| !data)
689692
return;
690693

691-
data=PG_DETOAST_DATUM(json->obj.compressed);
692-
693-
Assert(!VARATT_IS_EXTERNAL_EXTENDED(data));
694-
json->obj.compressed=PointerGetDatum(data);
694+
detoasted_data=PG_DETOAST_DATUM(json->obj.value);
695+
json->obj.value=PointerGetDatum(detoasted_data);
696+
json->obj.freeValue |=data!=detoasted_data;
695697

696-
json->root.ops->init(&json->root,json->obj.compressed,json->obj.options);
698+
json->root.ops->init(&json->root,json->obj.value,json->obj.options);
697699
}
698700

699701
staticSize
@@ -849,27 +851,42 @@ jsonExpandedObjectMethods =
849851
};
850852

851853
staticJson*
852-
JsonExpand(Datumvalue,JsonContainerOps*ops,CompressionOptionsoptions)
854+
JsonExpand(Json*tmp,Datumvalue,boolfreeValue,
855+
JsonContainerOps*ops,CompressionOptionsoptions)
853856
{
854857
MemoryContextobjcxt;
855858
Json*json;
856859

857-
/*
858-
* Allocate private context for expanded object. We start by assuming
859-
* that the json won't be very large; but if it does grow a lot, don't
860-
* constrain aset.c's large-context behavior.
861-
*/
862-
objcxt=AllocSetContextCreate(CurrentMemoryContext,
863-
"expanded json",
864-
ALLOCSET_SMALL_MINSIZE,
865-
ALLOCSET_SMALL_INITSIZE,
866-
ALLOCSET_DEFAULT_MAXSIZE);
867-
868-
json= (Json*)MemoryContextAlloc(objcxt,sizeof(Json));
860+
if (tmp)
861+
{
862+
json=tmp;
863+
json->obj.eoh.vl_len_=0;
864+
}
865+
else
866+
{
867+
#ifndefJSON_EXPANDED_OBJECT_MCXT
868+
json= (Json*)palloc(sizeof(Json));
869+
objcxt=NULL;
870+
#else
871+
/*
872+
* Allocate private context for expanded object. We start by assuming
873+
* that the json won't be very large; but if it does grow a lot, don't
874+
* constrain aset.c's large-context behavior.
875+
*/
876+
objcxt=AllocSetContextCreate(CurrentMemoryContext,
877+
"expanded json",
878+
ALLOCSET_SMALL_MINSIZE,
879+
ALLOCSET_SMALL_INITSIZE,
880+
ALLOCSET_DEFAULT_MAXSIZE);
881+
882+
json= (Json*)MemoryContextAlloc(objcxt,sizeof(Json));
883+
#endif
869884

870-
EOH_init_header(&json->obj.eoh,&jsonExpandedObjectMethods,objcxt);
885+
EOH_init_header(&json->obj.eoh,&jsonExpandedObjectMethods,objcxt);
886+
}
871887

872-
json->obj.compressed=value;
888+
json->obj.value=value;
889+
json->obj.freeValue=freeValue;
873890
json->obj.options=options;
874891
json->root.data=NULL;
875892
json->root.len=0;
@@ -882,7 +899,8 @@ JsonExpand(Datum value, JsonContainerOps *ops, CompressionOptions options)
882899
}
883900

884901
staticJson*
885-
JsonExpandDatum(Datumvalue,JsonContainerOps*ops,CompressionOptionsoptions)
902+
JsonExpandDatum(Datumvalue,JsonContainerOps*ops,CompressionOptionsoptions,
903+
Json*tmp)
886904
{
887905
structvarlena*toasted= (structvarlena*)DatumGetPointer(value);
888906
Json*json;
@@ -895,38 +913,65 @@ JsonExpandDatum(Datum value, JsonContainerOps *ops, CompressionOptions options)
895913

896914
if (VARATT_IS_EXTERNAL_EXTENDED(detoasted))
897915
#ifdefJSON_FLATTEN_INTO_JSONEXT
898-
returnJsonInitExtended(toasted,detoasted);
916+
returnJsonInitExtended(tmp,detoasted,toasted!=detoasted);
899917
#else
900918
elog(ERROR,"unexpected extended json");
901919
#endif
902920

903-
json=JsonExpand(PointerGetDatum(detoasted),ops,options);
921+
json=JsonExpand(tmp,PointerGetDatum(detoasted),toasted!=detoasted,
922+
ops,options);
904923
}
905924

906925
returnjson;
907926
}
908927

909928
Json*
910-
DatumGetJson(Datumvalue,JsonContainerOps*ops,CompressionOptionsoptions)
929+
DatumGetJson(Datumvalue,JsonContainerOps*ops,CompressionOptionsoptions,
930+
Json*tmp)
911931
{
912-
Json*json=JsonExpandDatum(value,ops,options);
932+
Json*json=JsonExpandDatum(value,ops,options,tmp);
913933
JsonInit(json);
914934
returnjson;
915935
}
916936

937+
void
938+
JsonFree(Json*json)
939+
{
940+
if (json->obj.freeValue)
941+
pfree(DatumGetPointer(json->obj.value));
942+
943+
if (!JsonIsTemporary(json))
944+
pfree(json);
945+
}
946+
947+
Json*
948+
JsonCopyTemporary(Json*tmp)
949+
{
950+
Json*json= (Json*)palloc(sizeof(Json));
951+
952+
memcpy(json,tmp,sizeof(Json));
953+
tmp->obj.freeValue= false;
954+
955+
EOH_init_header(&json->obj.eoh,&jsonExpandedObjectMethods,NULL);
956+
957+
returnjson;
958+
}
959+
917960
Json*
918961
JsonValueToJson(JsonValue*val)
919962
{
920963
if (val->type==jbvBinary)
921964
{
922965
JsonContainer*jc=val->val.binary.data;
923-
Json*json=JsonExpand(PointerGetDatum(NULL),jc->ops,NULL);
966+
Json*json=JsonExpand(NULL,PointerGetDatum(NULL), false,
967+
jc->ops,NULL);
924968
json->root=*jc;
925969
returnjson;
926970
}
927971
else
928972
{
929-
Json*json=JsonExpand(PointerGetDatum(NULL),&jsonvContainerOps,NULL);
973+
Json*json=JsonExpand(NULL,PointerGetDatum(NULL), false,
974+
&jsonvContainerOps,NULL);
930975
jsonvInitContainer(&json->root,val);
931976
returnjson;
932977
}

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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ jsonb_ne(PG_FUNCTION_ARGS)
144144

145145
res= (compareJsonbContainers(&jba->root,&jbb->root)!=0);
146146

147-
PG_FREE_IF_COPY(jba,0);
148-
PG_FREE_IF_COPY(jbb,1);
147+
PG_FREE_IF_COPY_JSONB(jba,0);
148+
PG_FREE_IF_COPY_JSONB(jbb,1);
149149
PG_RETURN_BOOL(res);
150150
}
151151

@@ -161,8 +161,8 @@ jsonb_lt(PG_FUNCTION_ARGS)
161161

162162
res= (compareJsonbContainers(&jba->root,&jbb->root)<0);
163163

164-
PG_FREE_IF_COPY(jba,0);
165-
PG_FREE_IF_COPY(jbb,1);
164+
PG_FREE_IF_COPY_JSONB(jba,0);
165+
PG_FREE_IF_COPY_JSONB(jbb,1);
166166
PG_RETURN_BOOL(res);
167167
}
168168

@@ -175,8 +175,8 @@ jsonb_gt(PG_FUNCTION_ARGS)
175175

176176
res= (compareJsonbContainers(&jba->root,&jbb->root)>0);
177177

178-
PG_FREE_IF_COPY(jba,0);
179-
PG_FREE_IF_COPY(jbb,1);
178+
PG_FREE_IF_COPY_JSONB(jba,0);
179+
PG_FREE_IF_COPY_JSONB(jbb,1);
180180
PG_RETURN_BOOL(res);
181181
}
182182

@@ -189,8 +189,8 @@ jsonb_le(PG_FUNCTION_ARGS)
189189

190190
res= (compareJsonbContainers(&jba->root,&jbb->root) <=0);
191191

192-
PG_FREE_IF_COPY(jba,0);
193-
PG_FREE_IF_COPY(jbb,1);
192+
PG_FREE_IF_COPY_JSONB(jba,0);
193+
PG_FREE_IF_COPY_JSONB(jbb,1);
194194
PG_RETURN_BOOL(res);
195195
}
196196

@@ -203,8 +203,8 @@ jsonb_ge(PG_FUNCTION_ARGS)
203203

204204
res= (compareJsonbContainers(&jba->root,&jbb->root) >=0);
205205

206-
PG_FREE_IF_COPY(jba,0);
207-
PG_FREE_IF_COPY(jbb,1);
206+
PG_FREE_IF_COPY_JSONB(jba,0);
207+
PG_FREE_IF_COPY_JSONB(jbb,1);
208208
PG_RETURN_BOOL(res);
209209
}
210210

@@ -217,8 +217,8 @@ jsonb_eq(PG_FUNCTION_ARGS)
217217

218218
res= (compareJsonbContainers(&jba->root,&jbb->root)==0);
219219

220-
PG_FREE_IF_COPY(jba,0);
221-
PG_FREE_IF_COPY(jbb,1);
220+
PG_FREE_IF_COPY_JSONB(jba,0);
221+
PG_FREE_IF_COPY_JSONB(jbb,1);
222222
PG_RETURN_BOOL(res);
223223
}
224224

@@ -231,8 +231,8 @@ jsonb_cmp(PG_FUNCTION_ARGS)
231231

232232
res=compareJsonbContainers(&jba->root,&jbb->root);
233233

234-
PG_FREE_IF_COPY(jba,0);
235-
PG_FREE_IF_COPY(jbb,1);
234+
PG_FREE_IF_COPY_JSONB(jba,0);
235+
PG_FREE_IF_COPY_JSONB(jbb,1);
236236
PG_RETURN_INT32(res);
237237
}
238238

@@ -277,6 +277,6 @@ jsonb_hash(PG_FUNCTION_ARGS)
277277
}
278278
}
279279

280-
PG_FREE_IF_COPY(jb,0);
280+
PG_FREE_IF_COPY_JSONB(jb,0);
281281
PG_RETURN_INT32(hash);
282282
}

‎src/include/c.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,21 @@ extern intfdatasync(int fildes);
11211121
#defineNON_EXEC_STATIC static
11221122
#endif
11231123

1124+
#ifndefalloca
1125+
# ifdef__GNUC__
1126+
# definealloca __builtin_alloca
1127+
# elif defined(__BUILTIN_VA_ARG_INCR)
1128+
# include<alloca.h>
1129+
# elif defined(_AIX)
1130+
# definealloca __alloca
1131+
# elif defined(_MSC_VER)
1132+
# include<malloc.h>
1133+
# definealloca _alloca
1134+
# elif defined(__STDC__)|| defined(__C99__FUNC__)
1135+
# include<stdlib.h>
1136+
# endif
1137+
#endif
1138+
11241139
/* /port compatibility functions */
11251140
#include"port.h"
11261141

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp