Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+8-8
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

+6-3
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

+50-9
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

+7-7
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

+16-16
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

+2-2
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

+15
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)