diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c
index b4bbdc89b1..307ac591be 100644
--- a/src/backend/executor/nodeProjectSet.c
+++ b/src/backend/executor/nodeProjectSet.c
@@ -72,20 +72,22 @@ ExecProjectSet(PlanState *pstate)
 			return resultSlot;
 	}
 
-	/*
-	 * Reset argument context to free any expression evaluation storage
-	 * allocated in the previous tuple cycle.  Note this can't happen until
-	 * we're done projecting out tuples from a scan tuple, as ValuePerCall
-	 * functions are allowed to reference the arguments for each returned
-	 * tuple.
-	 */
-	MemoryContextReset(node->argcontext);
-
 	/*
 	 * Get another input tuple and project SRFs from it.
 	 */
 	for (;;)
 	{
+		/*
+		 * Reset argument context to free any expression evaluation storage
+		 * allocated in the previous tuple cycle.  Note this can't happen
+		 * until we're done projecting out tuples from a scan tuple, as
+		 * ValuePerCall functions are allowed to reference the arguments for
+		 * each returned tuple.  However, if we loop around after finding that
+		 * no rows are produced from a scan tuple, we should reset, as the SRF
+		 * might well leak memory in that case.
+		 */
+		MemoryContextReset(node->argcontext);
+
 		/*
 		 * Retrieve tuples from the outer plan until there are no more.
 		 */
