From 91a1c0ce97346bef188e99d98a6de90741a1a0c8 Mon Sep 17 00:00:00 2001
From: "tender.wang" <tender.wang@openpie.com>
Date: Wed, 28 Feb 2024 14:40:00 +0800
Subject: [PATCH v4] Fix RangeType oid not found when doing Memoize.

After call ResetExprContext(), the data in mstate->proeslot may be freed too,
So we copy the result to probeslot from ExecEvalExpr.
---
 src/backend/executor/nodeMemoize.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/backend/executor/nodeMemoize.c b/src/backend/executor/nodeMemoize.c
index 18870f10e1..3790df71c0 100644
--- a/src/backend/executor/nodeMemoize.c
+++ b/src/backend/executor/nodeMemoize.c
@@ -312,17 +312,33 @@ prepare_probe_slot(MemoizeState *mstate, MemoizeKey *key)
 	if (key == NULL)
 	{
 		ExprContext *econtext = mstate->ss.ps.ps_ExprContext;
+		Datum value;
+		bool isnull;
+		TupleDesc tup = pslot->tts_tupleDescriptor;
+		Form_pg_attribute att;
 		MemoryContext oldcontext;
 
-		oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
-
 		/* Set the probeslot's values based on the current parameter values */
 		for (int i = 0; i < numKeys; i++)
-			pslot->tts_values[i] = ExecEvalExpr(mstate->param_exprs[i],
-												econtext,
-												&pslot->tts_isnull[i]);
-
-		MemoryContextSwitchTo(oldcontext);
+		{
+			att = TupleDescAttr(tup, i);
+			value = ExecEvalExprSwitchContext(mstate->param_exprs[i],
+											  econtext,
+											  &isnull);
+			if (isnull)
+			{
+				pslot->tts_values[i] = (Datum ) 0;
+				pslot->tts_isnull[i] = true;
+			}
+			else
+			{
+				/* Copy the value to avoid freed after resetting ExprContext */
+				oldcontext = MemoryContextSwitchTo(mstate->tableContext);
+				pslot->tts_values[i] = datumCopy(value, att->attbyval, att->attlen);
+				pslot->tts_isnull[i] = false;
+				MemoryContextSwitchTo(oldcontext);
+			}
+		}
 	}
 	else
 	{
-- 
2.25.1

