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)