On Wed, Jul 11, 2018 at 03:27:13PM +0900, Michael Paquier wrote:
> I don't think that your solution is correct.  From my read of 37a795a6,
> the tuple descriptor is moved from the query-lifespan memory context
> (ecxt_per_query_memory) to a function-level context, which could cause
> the descriptor to become busted as your test is pointing out.  Tom?

Hacking my way out I am finishing with the attached, which fixes the
problem and passes all regression tests.  I am not completely sure that
this the right approach though, I would need to think a bit more about
it.
--
Michael
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index e358b5ad13..b82060528b 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -2721,24 +2721,22 @@ JsValueToJsObject(JsValue *jsv, JsObject *jso)
 static void
 update_cached_tupdesc(CompositeIOData *io, MemoryContext mcxt)
 {
-	if (!io->tupdesc ||
-		io->tupdesc->tdtypeid != io->base_typid ||
-		io->tupdesc->tdtypmod != io->base_typmod)
-	{
-		TupleDesc	tupdesc = lookup_rowtype_tupdesc(io->base_typid,
-													 io->base_typmod);
-		MemoryContext oldcxt;
+	TupleDesc	tupdesc;
+	MemoryContext oldcxt;
 
-		if (io->tupdesc)
-			FreeTupleDesc(io->tupdesc);
+	if (io->tupdesc != NULL &&
+		io->tupdesc->tdtypeid == io->base_typid &&
+		io->tupdesc->tdtypmod == io->base_typmod)
+		return;
 
-		/* copy tuple desc without constraints into cache memory context */
-		oldcxt = MemoryContextSwitchTo(mcxt);
-		io->tupdesc = CreateTupleDescCopy(tupdesc);
-		MemoryContextSwitchTo(oldcxt);
+	tupdesc = lookup_rowtype_tupdesc(io->base_typid, io->base_typmod);
 
-		ReleaseTupleDesc(tupdesc);
-	}
+	/* copy tuple desc without constraints into cache memory context */
+	oldcxt = MemoryContextSwitchTo(mcxt);
+	io->tupdesc = CreateTupleDescCopy(tupdesc);
+	MemoryContextSwitchTo(oldcxt);
+
+	ReleaseTupleDesc(tupdesc);
 }
 
 /* recursively populate a composite (row type) value from json/jsonb */
@@ -3577,8 +3575,8 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
 	if (!cache)
 	{
 		fcinfo->flinfo->fn_extra = cache =
-			MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, sizeof(*cache));
-		cache->fn_mcxt = fcinfo->flinfo->fn_mcxt;
+			MemoryContextAllocZero(rsi->econtext->ecxt_per_query_memory, sizeof(*cache));
+		cache->fn_mcxt = rsi->econtext->ecxt_per_query_memory;
 
 		if (have_record_arg)
 		{

Attachment: signature.asc
Description: PGP signature

Reply via email to