diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 68a92dbac0142ee45be3ceb33e6c76c19c12c25d..15464c3dc66d35b254ba0f2f93228449265fcdfa 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -695,6 +695,12 @@ compute_index_stats(Relation onerel, double totalrows,
 		{
 			HeapTuple	heapTuple = rows[rowno];
 
+			/*
+			 * Reset the per-tuple context each time, to reclaim any cruft
+			 * left behind by evaluating the predicate or index expressions.
+			 */
+			ResetExprContext(econtext);
+
 			/* Set up for predicate or expression evaluation */
 			ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
 
@@ -719,15 +725,26 @@ compute_index_stats(Relation onerel, double totalrows,
 							   isnull);
 
 				/*
-				 * Save just the columns we care about.
+				 * Save just the columns we care about.  We copy the values
+				 * into ind_context from the estate's per-tuple context.
 				 */
 				for (i = 0; i < attr_cnt; i++)
 				{
 					VacAttrStats *stats = thisdata->vacattrstats[i];
 					int			attnum = stats->attr->attnum;
 
-					exprvals[tcnt] = values[attnum - 1];
-					exprnulls[tcnt] = isnull[attnum - 1];
+					if (isnull[attnum - 1])
+					{
+						exprvals[tcnt] = (Datum) 0;
+						exprnulls[tcnt] = true;
+					}
+					else
+					{
+						exprvals[tcnt] = datumCopy(values[attnum - 1],
+												   stats->attrtype->typbyval,
+												   stats->attrtype->typlen);
+						exprnulls[tcnt] = false;
+					}
 					tcnt++;
 				}
 			}