Skip to content

Commit d71f262

Browse files
author
Nikita Glukhov
committed
Add temporary stack-allocated expanded Jsons
1 parent 404852a commit d71f262

File tree

8 files changed

+126
-51
lines changed

8 files changed

+126
-51
lines changed

src/backend/tsearch/to_tsany.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ jsonb_string_to_tsvector_byid(PG_FUNCTION_ARGS)
304304
TSVector result;
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
uint32 flags = 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
}
@@ -413,7 +413,7 @@ json_to_tsvector_byid(PG_FUNCTION_ARGS)
413413

414414
result = json_to_tsvector_worker(cfgId, json, flags);
415415
PG_FREE_IF_COPY(json, 1);
416-
PG_FREE_IF_COPY(jbFlags, 2);
416+
PG_FREE_IF_COPY_JSONB(jbFlags, 2);
417417

418418
PG_RETURN_TSVECTOR(result);
419419
}
@@ -430,7 +430,7 @@ json_to_tsvector(PG_FUNCTION_ARGS)
430430
cfgId = getTSCurrentConfig(true);
431431
result = json_to_tsvector_worker(cfgId, json, flags);
432432
PG_FREE_IF_COPY(json, 0);
433-
PG_FREE_IF_COPY(jbFlags, 1);
433+
PG_FREE_IF_COPY_JSONB(jbFlags, 1);
434434

435435
PG_RETURN_TSVECTOR(result);
436436
}

src/backend/tsearch/wparser.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
381381
JsonTransformStringValuesAction action = (JsonTransformStringValuesAction) headline_json_value;
382382
HeadlineParsedText prs;
383383
HeadlineJsonState *state = palloc0(sizeof(HeadlineJsonState));
384+
Datum res;
384385

385386
memset(&prs, 0, sizeof(HeadlineParsedText));
386387
prs.lenwords = 32;
@@ -402,7 +403,10 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
402403

403404
out = transform_jsonb_string_values(jb, state, action);
404405

405-
PG_FREE_IF_COPY(jb, 1);
406+
/* flatten result to jsonb before jb freeing */
407+
res = JsonFlattenToJsonbDatum(out);
408+
409+
PG_FREE_IF_COPY_JSONB(jb, 1);
406410
PG_FREE_IF_COPY(query, 2);
407411
if (opt)
408412
PG_FREE_IF_COPY(opt, 3);
@@ -415,7 +419,7 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
415419
pfree(prs.stopsel);
416420
}
417421

418-
PG_RETURN_JSONB_P(out);
422+
PG_RETURN_DATUM(res);
419423
}
420424

421425
Datum
@@ -478,7 +482,6 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
478482
errmsg("text search parser does not support headline creation")));
479483

480484
out = transform_json_string_values(json, state, action);
481-
482485
PG_FREE_IF_COPY(json, 1);
483486
PG_FREE_IF_COPY(query, 2);
484487
if (opt)

src/backend/utils/adt/json_generic.c

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
static JsonContainerOps jsonvContainerOps;
1818

19-
static Json *JsonExpand(Datum value, JsonContainerOps *ops);
19+
static Json *JsonExpand(Json *tmp, Datum value, bool freeValue,
20+
JsonContainerOps *ops);
21+
2022

2123
#if 0
2224
static JsonValue *
@@ -594,11 +596,13 @@ JsonInit(Json *json)
594596
}
595597

596598
static Json *
597-
JsonExpand(Datum value, JsonContainerOps *ops)
599+
JsonExpand(Json *tmp, Datum value, bool freeValue, JsonContainerOps *ops)
598600
{
599-
Json *json = (Json *) palloc(sizeof(Json));
601+
Json *json = tmp ? tmp : (Json *) palloc(sizeof(Json));
600602

601603
json->obj.value = value;
604+
json->obj.freeValue = freeValue;
605+
json->obj.isTemporary = tmp != NULL;
602606
json->root.data = NULL;
603607
json->root.len = 0;
604608
json->root.ops = ops;
@@ -609,31 +613,68 @@ JsonExpand(Datum value, JsonContainerOps *ops)
609613
return json;
610614
}
611615

612-
Json *
613-
DatumGetJson(Datum value, JsonContainerOps *ops)
616+
static Json *
617+
JsonExpandDatum(Datum value, JsonContainerOps *ops, Json *tmp)
614618
{
615619
struct varlena *toasted = (struct varlena *) DatumGetPointer(value);
616620
struct varlena *detoasted = pg_detoast_datum(toasted);
617-
Json *json = JsonExpand(PointerGetDatum(detoasted), ops);
621+
Json *json = JsonExpand(tmp, PointerGetDatum(detoasted),
622+
toasted != detoasted, ops);
623+
624+
return json;
625+
}
626+
627+
Json *
628+
DatumGetJson(Datum value, JsonContainerOps *ops, Json *tmp)
629+
{
630+
Json *json = JsonExpandDatum(value, ops, tmp);
618631

619632
JsonInit(json);
620633

621634
return json;
622635
}
623636

637+
void
638+
JsonFree(Json *json)
639+
{
640+
if (json->obj.freeValue)
641+
pfree(DatumGetPointer(json->obj.value));
642+
643+
if (!JsonIsTemporary(json))
644+
pfree(json);
645+
}
646+
647+
Json *
648+
JsonCopyTemporary(Json *tmp)
649+
{
650+
Json *json = (Json *) palloc(sizeof(Json));
651+
652+
memcpy(json, tmp, sizeof(Json));
653+
tmp->obj.freeValue = false;
654+
json->obj.isTemporary = false;
655+
656+
return json;
657+
}
658+
624659
Json *
625660
JsonValueToJson(JsonValue *val)
626661
{
627662
if (val->type == jbvBinary)
628663
{
629-
Json *json = JsonExpand(PointerGetDatum(NULL), NULL);
630-
json->root = *val->val.binary.data;
664+
JsonContainer *jc = val->val.binary.data;
665+
Json *json = JsonExpand(NULL, PointerGetDatum(NULL), false,
666+
jc->ops);
667+
668+
json->root = *jc;
631669
return json;
632670
}
633671
else
634672
{
635-
Json *json = JsonExpand(PointerGetDatum(NULL), &jsonvContainerOps);
673+
Json *json = JsonExpand(NULL, PointerGetDatum(NULL), false,
674+
&jsonvContainerOps);
675+
636676
jsonvInitContainer(&json->root, val);
677+
637678
return json;
638679
}
639680
}

src/backend/utils/adt/jsonb.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ jsonb_bool(PG_FUNCTION_ARGS)
20302030
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
20312031
cannotCastJsonbValue(v.type, "boolean");
20322032

2033-
PG_FREE_IF_COPY(in, 0);
2033+
PG_FREE_IF_COPY_JSONB(in, 0);
20342034

20352035
PG_RETURN_BOOL(v.val.boolean);
20362036
}
@@ -2051,7 +2051,7 @@ jsonb_numeric(PG_FUNCTION_ARGS)
20512051
*/
20522052
retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
20532053

2054-
PG_FREE_IF_COPY(in, 0);
2054+
PG_FREE_IF_COPY_JSONB(in, 0);
20552055

20562056
PG_RETURN_NUMERIC(retValue);
20572057
}
@@ -2069,7 +2069,7 @@ jsonb_int2(PG_FUNCTION_ARGS)
20692069
retValue = DirectFunctionCall1(numeric_int2,
20702070
NumericGetDatum(v.val.numeric));
20712071

2072-
PG_FREE_IF_COPY(in, 0);
2072+
PG_FREE_IF_COPY_JSONB(in, 0);
20732073

20742074
PG_RETURN_DATUM(retValue);
20752075
}
@@ -2087,7 +2087,7 @@ jsonb_int4(PG_FUNCTION_ARGS)
20872087
retValue = DirectFunctionCall1(numeric_int4,
20882088
NumericGetDatum(v.val.numeric));
20892089

2090-
PG_FREE_IF_COPY(in, 0);
2090+
PG_FREE_IF_COPY_JSONB(in, 0);
20912091

20922092
PG_RETURN_DATUM(retValue);
20932093
}
@@ -2105,7 +2105,7 @@ jsonb_int8(PG_FUNCTION_ARGS)
21052105
retValue = DirectFunctionCall1(numeric_int8,
21062106
NumericGetDatum(v.val.numeric));
21072107

2108-
PG_FREE_IF_COPY(in, 0);
2108+
PG_FREE_IF_COPY_JSONB(in, 0);
21092109

21102110
PG_RETURN_DATUM(retValue);
21112111
}
@@ -2123,7 +2123,7 @@ jsonb_float4(PG_FUNCTION_ARGS)
21232123
retValue = DirectFunctionCall1(numeric_float4,
21242124
NumericGetDatum(v.val.numeric));
21252125

2126-
PG_FREE_IF_COPY(in, 0);
2126+
PG_FREE_IF_COPY_JSONB(in, 0);
21272127

21282128
PG_RETURN_DATUM(retValue);
21292129
}
@@ -2141,7 +2141,7 @@ jsonb_float8(PG_FUNCTION_ARGS)
21412141
retValue = DirectFunctionCall1(numeric_float8,
21422142
NumericGetDatum(v.val.numeric));
21432143

2144-
PG_FREE_IF_COPY(in, 0);
2144+
PG_FREE_IF_COPY_JSONB(in, 0);
21452145

21462146
PG_RETURN_DATUM(retValue);
21472147
}

src/backend/utils/adt/jsonb_op.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ jsonb_ne(PG_FUNCTION_ARGS)
154154

155155
res = (compareJsonbContainers(&jba->root, &jbb->root) != 0);
156156

157-
PG_FREE_IF_COPY(jba, 0);
158-
PG_FREE_IF_COPY(jbb, 1);
157+
PG_FREE_IF_COPY_JSONB(jba, 0);
158+
PG_FREE_IF_COPY_JSONB(jbb, 1);
159159
PG_RETURN_BOOL(res);
160160
}
161161

@@ -171,8 +171,8 @@ jsonb_lt(PG_FUNCTION_ARGS)
171171

172172
res = (compareJsonbContainers(&jba->root, &jbb->root) < 0);
173173

174-
PG_FREE_IF_COPY(jba, 0);
175-
PG_FREE_IF_COPY(jbb, 1);
174+
PG_FREE_IF_COPY_JSONB(jba, 0);
175+
PG_FREE_IF_COPY_JSONB(jbb, 1);
176176
PG_RETURN_BOOL(res);
177177
}
178178

@@ -185,8 +185,8 @@ jsonb_gt(PG_FUNCTION_ARGS)
185185

186186
res = (compareJsonbContainers(&jba->root, &jbb->root) > 0);
187187

188-
PG_FREE_IF_COPY(jba, 0);
189-
PG_FREE_IF_COPY(jbb, 1);
188+
PG_FREE_IF_COPY_JSONB(jba, 0);
189+
PG_FREE_IF_COPY_JSONB(jbb, 1);
190190
PG_RETURN_BOOL(res);
191191
}
192192

@@ -199,8 +199,8 @@ jsonb_le(PG_FUNCTION_ARGS)
199199

200200
res = (compareJsonbContainers(&jba->root, &jbb->root) <= 0);
201201

202-
PG_FREE_IF_COPY(jba, 0);
203-
PG_FREE_IF_COPY(jbb, 1);
202+
PG_FREE_IF_COPY_JSONB(jba, 0);
203+
PG_FREE_IF_COPY_JSONB(jbb, 1);
204204
PG_RETURN_BOOL(res);
205205
}
206206

@@ -213,8 +213,8 @@ jsonb_ge(PG_FUNCTION_ARGS)
213213

214214
res = (compareJsonbContainers(&jba->root, &jbb->root) >= 0);
215215

216-
PG_FREE_IF_COPY(jba, 0);
217-
PG_FREE_IF_COPY(jbb, 1);
216+
PG_FREE_IF_COPY_JSONB(jba, 0);
217+
PG_FREE_IF_COPY_JSONB(jbb, 1);
218218
PG_RETURN_BOOL(res);
219219
}
220220

@@ -227,8 +227,8 @@ jsonb_eq(PG_FUNCTION_ARGS)
227227

228228
res = (compareJsonbContainers(&jba->root, &jbb->root) == 0);
229229

230-
PG_FREE_IF_COPY(jba, 0);
231-
PG_FREE_IF_COPY(jbb, 1);
230+
PG_FREE_IF_COPY_JSONB(jba, 0);
231+
PG_FREE_IF_COPY_JSONB(jbb, 1);
232232
PG_RETURN_BOOL(res);
233233
}
234234

@@ -241,8 +241,8 @@ jsonb_cmp(PG_FUNCTION_ARGS)
241241

242242
res = compareJsonbContainers(&jba->root, &jbb->root);
243243

244-
PG_FREE_IF_COPY(jba, 0);
245-
PG_FREE_IF_COPY(jbb, 1);
244+
PG_FREE_IF_COPY_JSONB(jba, 0);
245+
PG_FREE_IF_COPY_JSONB(jbb, 1);
246246
PG_RETURN_INT32(res);
247247
}
248248

@@ -287,7 +287,7 @@ jsonb_hash(PG_FUNCTION_ARGS)
287287
}
288288
}
289289

290-
PG_FREE_IF_COPY(jb, 0);
290+
PG_FREE_IF_COPY_JSONB(jb, 0);
291291
PG_RETURN_INT32(hash);
292292
}
293293

@@ -330,6 +330,6 @@ jsonb_hash_extended(PG_FUNCTION_ARGS)
330330
}
331331
}
332332

333-
PG_FREE_IF_COPY(jb, 0);
333+
PG_FREE_IF_COPY_JSONB(jb, 0);
334334
PG_RETURN_UINT64(hash);
335335
}

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)
358358
res = executeJsonPath(jp, vars, getJsonPathVariableFromJsonb,
359359
jb, !silent, NULL, tz);
360360

361-
PG_FREE_IF_COPY(jb, 0);
361+
PG_FREE_IF_COPY_JSONB(jb, 0);
362362
PG_FREE_IF_COPY(jp, 1);
363363

364364
if (jperIsError(res))
@@ -414,7 +414,7 @@ jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)
414414
(void) executeJsonPath(jp, vars, getJsonPathVariableFromJsonb,
415415
jb, !silent, &found, tz);
416416

417-
PG_FREE_IF_COPY(jb, 0);
417+
PG_FREE_IF_COPY_JSONB(jb, 0);
418418
PG_FREE_IF_COPY(jp, 1);
419419

420420
if (JsonValueListLength(&found) == 1)

src/include/c.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,21 @@ typedef intptr_t sigjmp_buf[5];
13991399
#define NON_EXEC_STATIC static
14001400
#endif
14011401

1402+
#ifndef alloca
1403+
# ifdef __GNUC__
1404+
# define alloca __builtin_alloca
1405+
# elif defined(__BUILTIN_VA_ARG_INCR)
1406+
# include <alloca.h>
1407+
# elif defined(_AIX)
1408+
# define alloca __alloca
1409+
# elif defined(_MSC_VER)
1410+
# include <malloc.h>
1411+
# define alloca _alloca
1412+
# elif defined(__STDC__) || defined(__C99__FUNC__)
1413+
# include <stdlib.h>
1414+
# endif
1415+
#endif
1416+
14021417
/* /port compatibility functions */
14031418
#include "port.h"
14041419

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