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

Commit7d28bac

Browse files
author
Nikita Glukhov
committed
Add temporary stack-allocated expanded Jsons
1 parentaf398f9 commit7d28bac

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
@@ -304,7 +304,7 @@ jsonb_string_to_tsvector_byid(PG_FUNCTION_ARGS)
304304
TSVectorresult;
305305

306306
result=jsonb_to_tsvector_worker(cfgId,jb,jtiString);
307-
PG_FREE_IF_COPY(jb,1);
307+
PG_FREE_IF_COPY_JSONB(jb,1);
308308

309309
PG_RETURN_TSVECTOR(result);
310310
}
@@ -318,7 +318,7 @@ jsonb_string_to_tsvector(PG_FUNCTION_ARGS)
318318

319319
cfgId=getTSCurrentConfig(true);
320320
result=jsonb_to_tsvector_worker(cfgId,jb,jtiString);
321-
PG_FREE_IF_COPY(jb,0);
321+
PG_FREE_IF_COPY_JSONB(jb,0);
322322

323323
PG_RETURN_TSVECTOR(result);
324324
}
@@ -333,8 +333,8 @@ jsonb_to_tsvector_byid(PG_FUNCTION_ARGS)
333333
uint32flags=parse_jsonb_index_flags(jbFlags);
334334

335335
result=jsonb_to_tsvector_worker(cfgId,jb,flags);
336-
PG_FREE_IF_COPY(jb,1);
337-
PG_FREE_IF_COPY(jbFlags,2);
336+
PG_FREE_IF_COPY_JSONB(jb,1);
337+
PG_FREE_IF_COPY_JSONB(jbFlags,2);
338338

339339
PG_RETURN_TSVECTOR(result);
340340
}
@@ -350,8 +350,8 @@ jsonb_to_tsvector(PG_FUNCTION_ARGS)
350350

351351
cfgId=getTSCurrentConfig(true);
352352
result=jsonb_to_tsvector_worker(cfgId,jb,flags);
353-
PG_FREE_IF_COPY(jb,0);
354-
PG_FREE_IF_COPY(jbFlags,1);
353+
PG_FREE_IF_COPY_JSONB(jb,0);
354+
PG_FREE_IF_COPY_JSONB(jbFlags,1);
355355

356356
PG_RETURN_TSVECTOR(result);
357357
}
@@ -397,7 +397,11 @@ json_string_to_tsvector_byid(PG_FUNCTION_ARGS)
397397
TSVectorresult;
398398

399399
result=json_to_tsvector_worker(cfgId,json,jtiString);
400+
#ifndefJSON_GENERIC
400401
PG_FREE_IF_COPY(json,1);
402+
#else
403+
PG_FREE_IF_COPY_JSONB(json,1);
404+
#endif
401405

402406
PG_RETURN_TSVECTOR(result);
403407
}
@@ -415,7 +419,11 @@ json_string_to_tsvector(PG_FUNCTION_ARGS)
415419

416420
cfgId=getTSCurrentConfig(true);
417421
result=json_to_tsvector_worker(cfgId,json,jtiString);
422+
#ifndefJSON_GENERIC
418423
PG_FREE_IF_COPY(json,0);
424+
#else
425+
PG_FREE_IF_COPY_JSONB(json,0);
426+
#endif
419427

420428
PG_RETURN_TSVECTOR(result);
421429
}
@@ -434,8 +442,12 @@ json_to_tsvector_byid(PG_FUNCTION_ARGS)
434442
uint32flags=parse_jsonb_index_flags(jbFlags);
435443

436444
result=json_to_tsvector_worker(cfgId,json,flags);
445+
#ifndefJSON_GENERIC
437446
PG_FREE_IF_COPY(json,1);
438-
PG_FREE_IF_COPY(jbFlags,2);
447+
#else
448+
PG_FREE_IF_COPY_JSONB(json,1);
449+
#endif
450+
PG_FREE_IF_COPY_JSONB(jbFlags,2);
439451

440452
PG_RETURN_TSVECTOR(result);
441453
}
@@ -455,8 +467,12 @@ json_to_tsvector(PG_FUNCTION_ARGS)
455467

456468
cfgId=getTSCurrentConfig(true);
457469
result=json_to_tsvector_worker(cfgId,json,flags);
470+
#ifndefJSON_GENERIC
458471
PG_FREE_IF_COPY(json,0);
459-
PG_FREE_IF_COPY(jbFlags,1);
472+
#else
473+
PG_FREE_IF_COPY_JSONB(json,0);
474+
#endif
475+
PG_FREE_IF_COPY_JSONB(jbFlags,1);
460476

461477
PG_RETURN_TSVECTOR(result);
462478
}

‎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