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

Commit9b8181e

Browse files
author
Nikita Glukhov
committed
Add temporary stack-allocated expanded Jsons
1 parentd1f2f5a commit9b8181e

File tree

9 files changed

+196
-79
lines changed

9 files changed

+196
-79
lines changed

‎src/backend/tsearch/to_tsany.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ jsonb_string_to_tsvector_byid(PG_FUNCTION_ARGS)
294294
TSVectorresult;
295295

296296
result=jsonb_to_tsvector_worker(cfgId,jb,jtiString);
297-
PG_FREE_IF_COPY(jb,1);
297+
PG_FREE_IF_COPY_JSONB(jb,1);
298298

299299
PG_RETURN_TSVECTOR(result);
300300
}
@@ -308,7 +308,7 @@ jsonb_string_to_tsvector(PG_FUNCTION_ARGS)
308308

309309
cfgId=getTSCurrentConfig(true);
310310
result=jsonb_to_tsvector_worker(cfgId,jb,jtiString);
311-
PG_FREE_IF_COPY(jb,0);
311+
PG_FREE_IF_COPY_JSONB(jb,0);
312312

313313
PG_RETURN_TSVECTOR(result);
314314
}
@@ -323,8 +323,8 @@ jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
323323
uint32flags=parse_jsonb_index_flags(jbFlags);
324324

325325
result=jsonb_to_tsvector_worker(cfgId,jb,flags);
326-
PG_FREE_IF_COPY(jb,1);
327-
PG_FREE_IF_COPY(jbFlags,2);
326+
PG_FREE_IF_COPY_JSONB(jb,1);
327+
PG_FREE_IF_COPY_JSONB(jbFlags,2);
328328

329329
PG_RETURN_TSVECTOR(result);
330330
}
@@ -340,8 +340,8 @@ jsonb_to_tsvector(PG_FUNCTION_ARGS)
340340

341341
cfgId=getTSCurrentConfig(true);
342342
result=jsonb_to_tsvector_worker(cfgId,jb,flags);
343-
PG_FREE_IF_COPY(jb,0);
344-
PG_FREE_IF_COPY(jbFlags,1);
343+
PG_FREE_IF_COPY_JSONB(jb,0);
344+
PG_FREE_IF_COPY_JSONB(jbFlags,1);
345345

346346
PG_RETURN_TSVECTOR(result);
347347
}
@@ -387,7 +387,11 @@ json_string_to_tsvector_byid(PG_FUNCTION_ARGS)
387387
TSVectorresult;
388388

389389
result=json_to_tsvector_worker(cfgId,json,jtiString);
390+
#ifndefJSON_GENERIC
390391
PG_FREE_IF_COPY(json,1);
392+
#else
393+
PG_FREE_IF_COPY_JSONB(json,1);
394+
#endif
391395

392396
PG_RETURN_TSVECTOR(result);
393397
}
@@ -405,7 +409,11 @@ json_string_to_tsvector(PG_FUNCTION_ARGS)
405409

406410
cfgId=getTSCurrentConfig(true);
407411
result=json_to_tsvector_worker(cfgId,json,jtiString);
412+
#ifndefJSON_GENERIC
408413
PG_FREE_IF_COPY(json,0);
414+
#else
415+
PG_FREE_IF_COPY_JSONB(json,0);
416+
#endif
409417

410418
PG_RETURN_TSVECTOR(result);
411419
}
@@ -424,8 +432,12 @@ json_to_tsvector_byid(PG_FUNCTION_ARGS)
424432
uint32flags=parse_jsonb_index_flags(jbFlags);
425433

426434
result=json_to_tsvector_worker(cfgId,json,flags);
435+
#ifndefJSON_GENERIC
427436
PG_FREE_IF_COPY(json,1);
428-
PG_FREE_IF_COPY(jbFlags,2);
437+
#else
438+
PG_FREE_IF_COPY_JSONB(json,1);
439+
#endif
440+
PG_FREE_IF_COPY_JSONB(jbFlags,2);
429441

430442
PG_RETURN_TSVECTOR(result);
431443
}
@@ -445,8 +457,12 @@ json_to_tsvector(PG_FUNCTION_ARGS)
445457

446458
cfgId=getTSCurrentConfig(true);
447459
result=json_to_tsvector_worker(cfgId,json,flags);
460+
#ifndefJSON_GENERIC
448461
PG_FREE_IF_COPY(json,0);
449-
PG_FREE_IF_COPY(jbFlags,1);
462+
#else
463+
PG_FREE_IF_COPY_JSONB(json,0);
464+
#endif
465+
PG_FREE_IF_COPY_JSONB(jbFlags,1);
450466

451467
PG_RETURN_TSVECTOR(result);
452468
}

‎src/backend/tsearch/wparser.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
407407
/* flatten result to jsonb before jb freeing */
408408
res=JsonFlattenToJsonbDatum(out);
409409

410-
PG_FREE_IF_COPY(jb,1);
410+
PG_FREE_IF_COPY_JSONB(jb,1);
411411
PG_FREE_IF_COPY(query,2);
412412
if (opt)
413413
PG_FREE_IF_COPY(opt,3);
@@ -488,6 +488,7 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
488488

489489
#ifndefJSON_GENERIC
490490
out=transform_json_string_values(json,state,action);
491+
PG_FREE_IF_COPY(json,1);
491492
#else
492493
{
493494
Jsonb*jsonb=transform_jsonb_string_values(json,state,action);
@@ -496,10 +497,11 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
496497
out=cstring_to_text(str);
497498

498499
pfree(str);
500+
501+
PG_FREE_IF_COPY_JSONB(json,1);
499502
}
500503
#endif
501504

502-
PG_FREE_IF_COPY(json,1);
503505
PG_FREE_IF_COPY(query,2);
504506
if (opt)
505507
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: 89 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
staticJsonContainerOpsjsonvContainerOps;
1818

19-
staticJson*JsonExpand(Datumvalue,JsonContainerOps*ops);
19+
staticJson*JsonExpand(Json*tmp,Datumvalue,boolfreeValue,
20+
JsonContainerOps*ops);
21+
2022

2123
#if0
2224
staticJsonValue*
@@ -608,8 +610,7 @@ jsonWriteExtended(JsonContainer *jc, void *ptr, Size allocated_size)
608610
}
609611

610612
staticJson*
611-
JsonInitExtended(conststructvarlena*toasted,
612-
conststructvarlena*detoasted)
613+
JsonInitExtended(Json*tmp,structvarlena*extvalue,boolfreeValue)
613614
{
614615
JsonContainerOps*ops;
615616
CompressionMethodRoutine*cmr;
@@ -619,10 +620,12 @@ JsonInitExtended(const struct varlena *toasted,
619620
intlen;
620621
Datumvalue;
621622

622-
Assert(VARATT_IS_EXTERNAL_EXTENDED(detoasted));
623+
Assert(VARATT_IS_EXTERNAL_EXTENDED(extvalue));
624+
625+
pextjs= (varatt_extended_json*)VARDATA_EXTERNAL(extvalue);
626+
memcpy(&extjs,pextjs, offsetof(varatt_extended_json,data));
623627

624-
pextjs= (varatt_extended_json*)VARDATA_EXTERNAL(detoasted);
625-
memcpy(&extjs,pextjs, offsetof(varatt_extended_json,params));
628+
totalSize=extjs.vaext.size- offsetof(varatt_extended_json,data);
626629

627630
ops=JsonContainerGetOpsByType(extjs.type);
628631

@@ -642,8 +645,11 @@ JsonInitExtended(const struct varlena *toasted,
642645
SET_VARSIZE(val,VARHDRSZ+len);
643646
memcpy(VARDATA(val),&pextjs->params,len);
644647

648+
if (freeValue)
649+
pfree(extvalue);
650+
645651
if (ops)
646-
returnJsonExpand(PointerGetDatum(val),ops);
652+
returnJsonExpand(tmp,value, true,ops);
647653

648654
value=cmr->decompress(PointerGetDatum(val),NULL);
649655

@@ -656,19 +662,19 @@ JsonInitExtended(const struct varlena *toasted,
656662
staticvoid
657663
JsonInit(Json*json)
658664
{
659-
constvoid*data=DatumGetPointer(json->obj.compressed);
665+
constvoid*data=DatumGetPointer(json->obj.value);
666+
constvoid*detoasted_data;
660667

661668
Assert(json->root.data||data);
662669

663670
if (json->root.data|| !data)
664671
return;
665672

666-
data=PG_DETOAST_DATUM(json->obj.compressed);
667-
668-
/* Assert(!VARATT_IS_EXTERNAL_EXTENDED(data)); */
669-
json->obj.compressed=PointerGetDatum(data);
673+
detoasted_data=PG_DETOAST_DATUM(json->obj.value);
674+
json->obj.value=PointerGetDatum(detoasted_data);
675+
json->obj.freeValue |=data!=detoasted_data;
670676

671-
(*json->root.ops->init)(&json->root,json->obj.compressed);
677+
json->root.ops->init(&json->root,json->obj.value);
672678
}
673679

674680
staticSize
@@ -824,27 +830,41 @@ jsonExpandedObjectMethods =
824830
};
825831

826832
staticJson*
827-
JsonExpand(Datumvalue,JsonContainerOps*ops)
833+
JsonExpand(Json*tmp,Datumvalue,boolfreeValue,JsonContainerOps*ops)
828834
{
829835
MemoryContextobjcxt;
830836
Json*json;
831837

832-
/*
833-
* Allocate private context for expanded object. We start by assuming
834-
* that the json won't be very large; but if it does grow a lot, don't
835-
* constrain aset.c's large-context behavior.
836-
*/
837-
objcxt=AllocSetContextCreate(CurrentMemoryContext,
838-
"expanded json",
839-
ALLOCSET_SMALL_MINSIZE,
840-
ALLOCSET_SMALL_INITSIZE,
841-
ALLOCSET_DEFAULT_MAXSIZE);
842-
843-
json= (Json*)MemoryContextAlloc(objcxt,sizeof(Json));
838+
if (tmp)
839+
{
840+
json=tmp;
841+
json->obj.eoh.vl_len_=0;
842+
}
843+
else
844+
{
845+
#ifndefJSON_EXPANDED_OBJECT_MCXT
846+
json= (Json*)palloc(sizeof(Json));
847+
objcxt=NULL;
848+
#else
849+
/*
850+
* Allocate private context for expanded object. We start by assuming
851+
* that the json won't be very large; but if it does grow a lot, don't
852+
* constrain aset.c's large-context behavior.
853+
*/
854+
objcxt=AllocSetContextCreate(CurrentMemoryContext,
855+
"expanded json",
856+
ALLOCSET_SMALL_MINSIZE,
857+
ALLOCSET_SMALL_INITSIZE,
858+
ALLOCSET_DEFAULT_MAXSIZE);
859+
860+
json= (Json*)MemoryContextAlloc(objcxt,sizeof(Json));
861+
#endif
844862

845-
EOH_init_header(&json->obj.eoh,&jsonExpandedObjectMethods,objcxt);
863+
EOH_init_header(&json->obj.eoh,&jsonExpandedObjectMethods,objcxt);
864+
}
846865

847-
json->obj.compressed=value;
866+
json->obj.value=value;
867+
json->obj.freeValue=freeValue;
848868
json->root.data=NULL;
849869
json->root.len=0;
850870
json->root.ops=ops;
@@ -855,8 +875,8 @@ JsonExpand(Datum value, JsonContainerOps *ops)
855875
returnjson;
856876
}
857877

858-
Json*
859-
DatumGetJson(Datumvalue,JsonContainerOps*ops)
878+
staticJson*
879+
JsonExpandDatum(Datumvalue,JsonContainerOps*ops,Json*tmp)
860880
{
861881
structvarlena*toasted= (structvarlena*)DatumGetPointer(value);
862882
Json*json;
@@ -870,32 +890,66 @@ DatumGetJson(Datum value, JsonContainerOps *ops)
870890
/*
871891
if (VARATT_IS_EXTERNAL_EXTENDED(detoasted))
872892
#ifdef JSON_FLATTEN_INTO_JSONEXT
873-
return JsonInitExtended(toasted, detoasted);
893+
return JsonInitExtended(tmp, detoasted, toasted != detoasted);
874894
#else
875895
elog(ERROR, "unexpected extended json");
876896
#endif
877897
*/
878898

879-
json=JsonExpand(PointerGetDatum(detoasted),ops);
899+
json=JsonExpand(tmp,PointerGetDatum(detoasted),toasted!=detoasted,
900+
ops);
880901
}
881902

903+
returnjson;
904+
}
905+
906+
Json*
907+
DatumGetJson(Datumvalue,JsonContainerOps*ops,Json*tmp)
908+
{
909+
Json*json=JsonExpandDatum(value,ops,tmp);
882910
JsonInit(json);
883911

884912
returnjson;
885913
}
886914

915+
void
916+
JsonFree(Json*json)
917+
{
918+
if (json->obj.freeValue)
919+
pfree(DatumGetPointer(json->obj.value));
920+
921+
if (!JsonIsTemporary(json))
922+
pfree(json);
923+
}
924+
925+
Json*
926+
JsonCopyTemporary(Json*tmp)
927+
{
928+
Json*json= (Json*)palloc(sizeof(Json));
929+
930+
memcpy(json,tmp,sizeof(Json));
931+
tmp->obj.freeValue= false;
932+
933+
EOH_init_header(&json->obj.eoh,&jsonExpandedObjectMethods,NULL);
934+
935+
returnjson;
936+
}
937+
887938
Json*
888939
JsonValueToJson(JsonValue*val)
889940
{
890941
if (val->type==jbvBinary)
891942
{
892-
Json*json=JsonExpand(PointerGetDatum(NULL),NULL);
893-
json->root=*val->val.binary.data;
943+
JsonContainer*jc=val->val.binary.data;
944+
Json*json=JsonExpand(NULL,PointerGetDatum(NULL), false,
945+
jc->ops);
946+
json->root=*jc;
894947
returnjson;
895948
}
896949
else
897950
{
898-
Json*json=JsonExpand(PointerGetDatum(NULL),&jsonvContainerOps);
951+
Json*json=JsonExpand(NULL,PointerGetDatum(NULL), false,
952+
&jsonvContainerOps);
899953
jsonvInitContainer(&json->root,val);
900954
returnjson;
901955
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp