Skip to content

Commit aa2e9dc

Browse files
author
Nikita Glukhov
committed
Optimize expanded object flattening: add context
1 parent 9b8181e commit aa2e9dc

File tree

10 files changed

+63
-44
lines changed

10 files changed

+63
-44
lines changed

src/backend/access/common/detoast.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ detoast_external_attr(struct varlena *attr)
8383
*/
8484
ExpandedObjectHeader *eoh;
8585
Size resultsize;
86+
void *context;
8687

8788
eoh = DatumGetEOHP(PointerGetDatum(attr));
88-
resultsize = EOH_get_flat_size(eoh);
89+
resultsize = EOH_get_flat_size(eoh, &context);
8990
result = (struct varlena *) palloc(resultsize);
90-
EOH_flatten_into(eoh, (void *) result, resultsize);
91+
EOH_flatten_into(eoh, (void *) result, resultsize, &context);
9192
}
9293
else
9394
{
@@ -525,7 +526,7 @@ toast_raw_datum_size(Datum value)
525526
}
526527
else if (VARATT_IS_EXTERNAL_EXPANDED(attr))
527528
{
528-
result = EOH_get_flat_size(DatumGetEOHP(value));
529+
result = EOH_get_flat_size(DatumGetEOHP(value), NULL);
529530
}
530531
else if (VARATT_IS_COMPRESSED(attr))
531532
{
@@ -585,7 +586,7 @@ toast_datum_size(Datum value)
585586
}
586587
else if (VARATT_IS_EXTERNAL_EXPANDED(attr))
587588
{
588-
result = EOH_get_flat_size(DatumGetEOHP(value));
589+
result = EOH_get_flat_size(DatumGetEOHP(value), NULL);
589590
}
590591
else if (VARATT_IS_SHORT(attr))
591592
{

src/backend/access/common/heaptuple.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ heap_compute_data_size(TupleDesc tupleDesc,
152152
* tuple doesn't depend on it
153153
*/
154154
data_length = att_align_nominal(data_length, atti->attalign);
155-
data_length += EOH_get_flat_size(DatumGetEOHP(val));
155+
data_length += EOH_get_flat_size(DatumGetEOHP(val), NULL);
156156
}
157157
else
158158
{
@@ -233,11 +233,12 @@ fill_val(Form_pg_attribute att,
233233
* constructed tuple doesn't depend on it
234234
*/
235235
ExpandedObjectHeader *eoh = DatumGetEOHP(datum);
236+
void *context;
236237

237238
data = (char *) att_align_nominal(data,
238239
att->attalign);
239-
data_length = EOH_get_flat_size(eoh);
240-
EOH_flatten_into(eoh, data, data_length);
240+
data_length = EOH_get_flat_size(eoh, &context);
241+
EOH_flatten_into(eoh, data, data_length, &context);
241242
}
242243
else
243244
{

src/backend/executor/execTuples.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ tts_virtual_materialize(TupleTableSlot *slot)
178178
* slot doesn't depend on it.
179179
*/
180180
sz = att_align_nominal(sz, att->attalign);
181-
sz += EOH_get_flat_size(DatumGetEOHP(val));
181+
sz += EOH_get_flat_size(DatumGetEOHP(val), NULL);
182182
}
183183
else
184184
{
@@ -216,11 +216,12 @@ tts_virtual_materialize(TupleTableSlot *slot)
216216
* slot doesn't depend on it.
217217
*/
218218
ExpandedObjectHeader *eoh = DatumGetEOHP(val);
219+
void *context;
219220

220221
data = (char *) att_align_nominal(data,
221222
att->attalign);
222-
data_length = EOH_get_flat_size(eoh);
223-
EOH_flatten_into(eoh, data, data_length);
223+
data_length = EOH_get_flat_size(eoh, &context);
224+
EOH_flatten_into(eoh, data, data_length, &context);
224225

225226
slot->tts_values[natt] = PointerGetDatum(data);
226227
data += data_length;

src/backend/utils/adt/array_expanded.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222

2323
/* "Methods" required for an expanded object */
24-
static Size EA_get_flat_size(ExpandedObjectHeader *eohptr);
24+
static Size EA_get_flat_size(ExpandedObjectHeader *eohptr, void **context);
2525
static void EA_flatten_into(ExpandedObjectHeader *eohptr,
26-
void *result, Size allocated_size);
26+
void *result, Size allocated_size, void **context);
2727

2828
static const ExpandedObjectMethods EA_methods =
2929
{
@@ -230,7 +230,7 @@ copy_byval_expanded_array(ExpandedArrayHeader *eah,
230230
* get_flat_size method for expanded arrays
231231
*/
232232
static Size
233-
EA_get_flat_size(ExpandedObjectHeader *eohptr)
233+
EA_get_flat_size(ExpandedObjectHeader *eohptr, void **context)
234234
{
235235
ExpandedArrayHeader *eah = (ExpandedArrayHeader *) eohptr;
236236
int nelems;
@@ -291,7 +291,7 @@ EA_get_flat_size(ExpandedObjectHeader *eohptr)
291291
*/
292292
static void
293293
EA_flatten_into(ExpandedObjectHeader *eohptr,
294-
void *result, Size allocated_size)
294+
void *result, Size allocated_size, void **context)
295295
{
296296
ExpandedArrayHeader *eah = (ExpandedArrayHeader *) eohptr;
297297
ArrayType *aresult = (ArrayType *) result;

src/backend/utils/adt/datum.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,11 @@ datumCopy(Datum value, bool typByVal, int typLen)
145145
ExpandedObjectHeader *eoh = DatumGetEOHP(value);
146146
Size resultsize;
147147
char *resultptr;
148+
void *context;
148149

149-
resultsize = EOH_get_flat_size(eoh);
150+
resultsize = EOH_get_flat_size(eoh, &context);
150151
resultptr = (char *) palloc(resultsize);
151-
EOH_flatten_into(eoh, (void *) resultptr, resultsize);
152+
EOH_flatten_into(eoh, (void *) resultptr, resultsize, &context);
152153
res = PointerGetDatum(resultptr);
153154
}
154155
else
@@ -370,7 +371,9 @@ datumEstimateSpace(Datum value, bool isnull, bool typByVal, int typLen)
370371
VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(value)))
371372
{
372373
/* Expanded objects need to be flattened, see comment below */
373-
sz += EOH_get_flat_size(DatumGetEOHP(value));
374+
ExpandedObjectHeader *eoh = DatumGetEOHP(value);
375+
376+
sz += EOH_get_flat_size(eoh, NULL);
374377
}
375378
else
376379
sz += datumGetSize(value, typByVal, typLen);
@@ -408,6 +411,7 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
408411
char **start_address)
409412
{
410413
ExpandedObjectHeader *eoh = NULL;
414+
void *context;
411415
int header;
412416

413417
/* Write header word. */
@@ -419,7 +423,7 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
419423
VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(value)))
420424
{
421425
eoh = DatumGetEOHP(value);
422-
header = EOH_get_flat_size(eoh);
426+
header = EOH_get_flat_size(eoh, &context);
423427
}
424428
else
425429
header = datumGetSize(value, typByVal, typLen);
@@ -443,7 +447,7 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
443447
* so we can't store directly to *start_address.
444448
*/
445449
tmp = (char *) palloc(header);
446-
EOH_flatten_into(eoh, (void *) tmp, header);
450+
EOH_flatten_into(eoh, (void *) tmp, header, &context);
447451
memcpy(*start_address, tmp, header);
448452
*start_address += header;
449453

src/backend/utils/adt/expandeddatum.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,16 @@ EOH_init_header(ExpandedObjectHeader *eohptr,
7373
*/
7474

7575
Size
76-
EOH_get_flat_size(ExpandedObjectHeader *eohptr)
76+
EOH_get_flat_size(ExpandedObjectHeader *eohptr, void **context)
7777
{
78-
return eohptr->eoh_methods->get_flat_size(eohptr);
78+
return eohptr->eoh_methods->get_flat_size(eohptr, context);
7979
}
8080

8181
void
8282
EOH_flatten_into(ExpandedObjectHeader *eohptr,
83-
void *result, Size allocated_size)
83+
void *result, Size allocated_size, void **context)
8484
{
85-
eohptr->eoh_methods->flatten_into(eohptr, result, allocated_size);
85+
eohptr->eoh_methods->flatten_into(eohptr, result, allocated_size, context);
8686
}
8787

8888
/*

src/backend/utils/adt/expandedrecord.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131

3232

3333
/* "Methods" required for an expanded object */
34-
static Size ER_get_flat_size(ExpandedObjectHeader *eohptr);
34+
static Size ER_get_flat_size(ExpandedObjectHeader *eohptr, void **context);
3535
static void ER_flatten_into(ExpandedObjectHeader *eohptr,
36-
void *result, Size allocated_size);
36+
void *result, Size allocated_size, void **context);
3737

3838
static const ExpandedObjectMethods ER_methods =
3939
{
@@ -649,7 +649,7 @@ make_expanded_record_from_datum(Datum recorddatum, MemoryContext parentcontext)
649649
* memory leaks from activities such as detoasting.
650650
*/
651651
static Size
652-
ER_get_flat_size(ExpandedObjectHeader *eohptr)
652+
ER_get_flat_size(ExpandedObjectHeader *eohptr, void **context)
653653
{
654654
ExpandedRecordHeader *erh = (ExpandedRecordHeader *) eohptr;
655655
TupleDesc tupdesc;
@@ -762,7 +762,7 @@ ER_get_flat_size(ExpandedObjectHeader *eohptr)
762762
*/
763763
static void
764764
ER_flatten_into(ExpandedObjectHeader *eohptr,
765-
void *result, Size allocated_size)
765+
void *result, Size allocated_size, void **context)
766766
{
767767
ExpandedRecordHeader *erh = (ExpandedRecordHeader *) eohptr;
768768
HeapTupleHeader tuphdr = (HeapTupleHeader) result;

src/backend/utils/adt/json_generic.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ JsonInit(Json *json)
678678
}
679679

680680
static Size
681-
jsonGetFlatSize2(Json *json)
681+
jsonGetFlatSize2(Json *json, void **context)
682682
{
683683
Size size;
684684

@@ -693,7 +693,10 @@ jsonGetFlatSize2(Json *json)
693693
{
694694
char *str = JsonToCString(&json->root);
695695
size = VARHDRSZ + strlen(str);
696-
pfree(str);
696+
if (context)
697+
*context = str;
698+
else
699+
pfree(str);
697700
}
698701
}
699702
#endif
@@ -709,7 +712,10 @@ jsonGetFlatSize2(Json *json)
709712
JsonValue val;
710713
void *js = JsonValueToJsonb(JsonToJsonValue(json, &val));
711714
size = VARSIZE(js);
712-
pfree(js);
715+
if (context)
716+
*context = js;
717+
else
718+
pfree(js);
713719
}
714720
}
715721
#endif
@@ -718,7 +724,7 @@ jsonGetFlatSize2(Json *json)
718724
}
719725

720726
static void *
721-
jsonFlatten(Json *json)
727+
jsonFlatten(Json *json, void **context)
722728
{
723729
#ifdef JSON_FLATTEN_INTO_TARGET
724730
if (json->is_json)
@@ -729,7 +735,7 @@ jsonFlatten(Json *json)
729735
return cstring_to_text_with_len(json->root.data, json->root.len);
730736
else
731737
{
732-
char *str = JsonToCString(JsonRoot(json));
738+
char *str = context ? (char *) *context : JsonToCString(JsonRoot(json));
733739
text *text = cstring_to_text(str);
734740
pfree(str);
735741
return text;
@@ -748,6 +754,8 @@ jsonFlatten(Json *json)
748754
memcpy(VARDATA(res), json->root.data, json->root.len);
749755
return res;
750756
}
757+
else if (context)
758+
return *context;
751759
else
752760
{
753761
JsonValue val;
@@ -758,7 +766,7 @@ jsonFlatten(Json *json)
758766
}
759767

760768
static Size
761-
jsonGetFlatSize(ExpandedObjectHeader *eoh)
769+
jsonGetFlatSize(ExpandedObjectHeader *eoh, void **context)
762770
{
763771
Json *json = (Json *) eoh;
764772

@@ -773,19 +781,20 @@ jsonGetFlatSize(ExpandedObjectHeader *eoh)
773781
{
774782
tmp.data = NULL;
775783
tmp.ops = flatContainerOps;
776-
tmp.len = jsonGetFlatSize2(json) - VARHDRSZ;
784+
tmp.len = jsonGetFlatSize2(json, context) - VARHDRSZ;
777785
flat = &tmp;
778786
}
779787

780788
return jsonGetExtendedSize(flat);
781789
}
782790
#else
783-
return jsonGetFlatSize2(json);
791+
return jsonGetFlatSize2(json, context);
784792
#endif
785793
}
786794

787795
static void
788-
jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size)
796+
jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size,
797+
void **context)
789798
{
790799
Json *json = (Json *) eoh;
791800

@@ -799,7 +808,7 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size)
799808

800809
if (flat->ops == &jsonvContainerOps)
801810
{
802-
tmpData = jsonFlatten(json);
811+
tmpData = jsonFlatten(json, context);
803812

804813
tmp.ops = flatContainerOps;
805814
tmp.data = VARDATA(tmpData);
@@ -815,7 +824,7 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size)
815824
}
816825
#else
817826
{
818-
void *data = jsonFlatten(json);
827+
void *data = jsonFlatten(json, context);
819828
memcpy(result, data, allocated_size);
820829
pfree(data);
821830
}

src/include/utils/expandeddatum.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@
6464
* get_flat_size twice, so it's worthwhile to make sure that that doesn't
6565
* incur too much overhead.
6666
*/
67-
typedef Size (*EOM_get_flat_size_method) (ExpandedObjectHeader *eohptr);
67+
typedef Size (*EOM_get_flat_size_method) (ExpandedObjectHeader *eohptr,
68+
void **context);
6869
typedef void (*EOM_flatten_into_method) (ExpandedObjectHeader *eohptr,
69-
void *result, Size allocated_size);
70+
void *result, Size allocated_size,
71+
void **context);
7072

7173
/* Struct of function pointers for an expanded object's methods */
7274
typedef struct ExpandedObjectMethods
@@ -149,9 +151,9 @@ extern ExpandedObjectHeader *DatumGetEOHP(Datum d);
149151
extern void EOH_init_header(ExpandedObjectHeader *eohptr,
150152
const ExpandedObjectMethods *methods,
151153
MemoryContext obj_context);
152-
extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr);
154+
extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr, void **context);
153155
extern void EOH_flatten_into(ExpandedObjectHeader *eohptr,
154-
void *result, Size allocated_size);
156+
void *result, Size allocated_size, void **context);
155157
extern Datum MakeExpandedObjectReadOnlyInternal(Datum d);
156158
extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent);
157159
extern void DeleteExpandedObject(Datum d);

src/pl/plpgsql/src/pl_exec.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -842,10 +842,11 @@ coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
842842
*/
843843
Size resultsize;
844844
HeapTupleHeader tuphdr;
845+
void *context;
845846

846-
resultsize = EOH_get_flat_size(&erh->hdr);
847+
resultsize = EOH_get_flat_size(&erh->hdr, &context);
847848
tuphdr = (HeapTupleHeader) SPI_palloc(resultsize);
848-
EOH_flatten_into(&erh->hdr, (void *) tuphdr, resultsize);
849+
EOH_flatten_into(&erh->hdr, (void *) tuphdr, resultsize, &context);
849850
HeapTupleHeaderSetTypeId(tuphdr, tupdesc->tdtypeid);
850851
HeapTupleHeaderSetTypMod(tuphdr, tupdesc->tdtypmod);
851852
estate->retval = PointerGetDatum(tuphdr);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy