Skip to content

Commit bd947cf

Browse files
author
Nikita Glukhov
committed
Fix jsonb TOAST iterators allocation/freeing
1 parent 6b55c5a commit bd947cf

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

src/backend/utils/adt/jsonb_util.c

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2961,7 +2961,14 @@ jsonbzIteratorInit(JsonContainer *jc)
29612961
return jsonbIteratorInitExt(jc, jbc, cjb);
29622962
}
29632963

2964-
List **jsonb_detoast_iterators;
2964+
#define JSONB_FREE_ITERATORS
2965+
#ifdef JSONB_FREE_ITERATORS
2966+
static struct
2967+
{
2968+
List *iterators;
2969+
MemoryContext mcxt;
2970+
} *jsonb_detoast_iterators;
2971+
#endif
29652972

29662973
static void
29672974
#ifndef JSONB_DETOAST_ITERATOR
@@ -2987,12 +2994,6 @@ jsonbzInitFromDetoastIterator(JsonContainerData *jc, DetoastIterator iter)
29872994
cjb->iter = iter;
29882995
cjb->offset = offsetof(JsonbDatum, root);
29892996

2990-
#define JSONB_FREE_ITERATORS
2991-
#ifdef JSONB_FREE_ITERATORS
2992-
if (jsonb_detoast_iterators)
2993-
*jsonb_detoast_iterators = lappend(*jsonb_detoast_iterators, iter);
2994-
#endif
2995-
29962997
if (!jsonb_partial_decompression)
29972998
PG_DETOAST_ITERATE(iter, iter->buf->capacity);
29982999
else
@@ -3006,7 +3007,9 @@ void
30063007
jsonbInitIterators(void)
30073008
{
30083009
#ifdef JSONB_FREE_ITERATORS
3009-
jsonb_detoast_iterators = palloc0(sizeof(*jsonb_detoast_iterators));
3010+
jsonb_detoast_iterators = palloc(sizeof(*jsonb_detoast_iterators));
3011+
jsonb_detoast_iterators->mcxt = CurrentMemoryContext;
3012+
jsonb_detoast_iterators->iterators = NIL;
30103013
#endif
30113014
}
30123015

@@ -3017,10 +3020,13 @@ jsonbFreeIterators(void)
30173020
ListCell *lc;
30183021

30193022
if (jsonb_detoast_iterators)
3020-
foreach(lc, *jsonb_detoast_iterators)
3023+
{
3024+
foreach(lc, jsonb_detoast_iterators->iterators)
30213025
free_detoast_iterator(lfirst(lc));
30223026

3023-
jsonb_detoast_iterators = NULL;
3027+
pfree(jsonb_detoast_iterators);
3028+
jsonb_detoast_iterators = NULL;
3029+
}
30243030
#endif
30253031
}
30263032

@@ -3045,8 +3051,19 @@ jsonbzInit(JsonContainerData *jc, Datum value)
30453051

30463052
jsonbzInitFromCompresedDatum(jc, cd);
30473053
#else
3054+
#ifdef JSONB_FREE_ITERATORS
3055+
MemoryContext oldcxt = jsonb_detoast_iterators ? MemoryContextSwitchTo(jsonb_detoast_iterators->mcxt) : NULL;
3056+
#endif
30483057
DetoastIterator iter = create_detoast_iterator((struct varlena *) DatumGetPointer(value));
30493058

3059+
#ifdef JSONB_FREE_ITERATORS
3060+
if (jsonb_detoast_iterators)
3061+
{
3062+
jsonb_detoast_iterators->iterators = lappend(jsonb_detoast_iterators->iterators, iter);
3063+
MemoryContextSwitchTo(oldcxt);
3064+
}
3065+
#endif
3066+
30503067
jsonbzInitFromDetoastIterator(jc, iter);
30513068
#endif
30523069
}
@@ -3105,13 +3122,23 @@ DatumGetJsonbPC(Datum datum, Json *tmp, bool copy)
31053122
if (!cd.compressed)
31063123
return DatumGetJson(PointerGetDatum(cd.data), &jsonbContainerOps, tmp);
31073124
#else
3125+
# ifdef JSONB_FREE_ITERATORS
3126+
MemoryContext oldcxt = jsonb_detoast_iterators ? MemoryContextSwitchTo(jsonb_detoast_iterators->mcxt) : NULL;
3127+
# endif
3128+
31083129
if (!jsonb_partial_detoast)
31093130
src = detoast_external_attr(src);
31103131

31113132
iter = create_detoast_iterator(src);
31123133

31133134
if (!iter)
3135+
{
3136+
# ifdef JSONB_FREE_ITERATORS
3137+
if (jsonb_detoast_iterators)
3138+
MemoryContextSwitchTo(oldcxt);
3139+
# endif
31143140
return DatumGetJson(PointerGetDatum(src), &jsonbContainerOps, tmp);
3141+
}
31153142
#endif
31163143

31173144
js = JsonExpand(tmp, (Datum) 0, false, &jsonbzContainerOps);
@@ -3121,6 +3148,15 @@ DatumGetJsonbPC(Datum datum, Json *tmp, bool copy)
31213148
memcpy(palloc(sizeof(cd)), &cd, sizeof(cd)));
31223149
#else
31233150
jsonbzInitFromDetoastIterator(&js->root, iter);
3151+
3152+
# ifdef JSONB_FREE_ITERATORS
3153+
if (jsonb_detoast_iterators)
3154+
{
3155+
jsonb_detoast_iterators->iterators = lappend(jsonb_detoast_iterators->iterators, iter);
3156+
MemoryContextSwitchTo(oldcxt);
3157+
}
3158+
# endif
31243159
#endif
3160+
31253161
return js;
31263162
}

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