@@ -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
29662973static 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
30063007jsonbInitIterators (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