diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 9929e04e57bbc7d08938765b7f506c05c07b772b..1f40f3cf69234ff650ece2ccb09791f8e075ec1a 100644
*** a/src/pl/plpgsql/src/pl_exec.c
--- b/src/pl/plpgsql/src/pl_exec.c
*************** loop_exit:
*** 4491,4497 ****
   *								a Datum by directly calling ExecEvalExpr().
   *
   * If successful, store results into *result, *isNull, *rettype and return
!  * TRUE.  If the expression is not simple (any more), return FALSE.
   *
   * It is possible though unlikely for a simple expression to become non-simple
   * (consider for example redefining a trivial view).  We must handle that for
--- 4491,4508 ----
   *								a Datum by directly calling ExecEvalExpr().
   *
   * If successful, store results into *result, *isNull, *rettype and return
!  * TRUE.  If the expression cannot be handled by simple evaluation,
!  * return FALSE.
!  *
!  * Because we only store one execution tree for a simple expression, we
!  * can't handle recursion cases.  So, if we see the tree is already busy
!  * with an evaluation in the current xact, we just return FALSE and let the
!  * caller run the expression the hard way.  (Other alternatives such as
!  * creating a new tree for a recursive call either introduce memory leaks,
!  * or add enough bookkeeping to be doubtful wins anyway.)  Another case that
!  * is covered by the expr_simple_in_use test is where a previous execution
!  * of the tree was aborted by an error: the tree may contain bogus state
!  * so we dare not re-use it.
   *
   * It is possible though unlikely for a simple expression to become non-simple
   * (consider for example redefining a trivial view).  We must handle that for
*************** exec_eval_simple_expr(PLpgSQL_execstate 
*** 4528,4533 ****
--- 4539,4550 ----
  		return false;
  
  	/*
+ 	 * If expression is in use in current xact, don't touch it.
+ 	 */
+ 	if (expr->expr_simple_in_use && expr->expr_simple_lxid == curlxid)
+ 		return false;
+ 
+ 	/*
  	 * Revalidate cached plan, so that we will notice if it became stale. (We
  	 * also need to hold a refcount while using the plan.)	Note that even if
  	 * replanning occurs, the length of plancache_list can't change, since it
*************** exec_eval_simple_expr(PLpgSQL_execstate 
*** 4562,4567 ****
--- 4579,4585 ----
  	{
  		expr->expr_simple_state = ExecPrepareExpr(expr->expr_simple_expr,
  												  simple_eval_estate);
+ 		expr->expr_simple_in_use = false;
  		expr->expr_simple_lxid = curlxid;
  	}
  
*************** exec_eval_simple_expr(PLpgSQL_execstate 
*** 4597,4602 ****
--- 4615,4625 ----
  	econtext->ecxt_param_list_info = paramLI;
  
  	/*
+ 	 * Mark expression as busy for the duration of the ExecEvalExpr call.
+ 	 */
+ 	expr->expr_simple_in_use = true;
+ 
+ 	/*
  	 * Finally we can call the executor to evaluate the expression
  	 */
  	*result = ExecEvalExpr(expr->expr_simple_state,
*************** exec_eval_simple_expr(PLpgSQL_execstate 
*** 4605,4610 ****
--- 4628,4635 ----
  						   NULL);
  
  	/* Assorted cleanup */
+ 	expr->expr_simple_in_use = false;
+ 
  	estate->cur_expr = save_cur_expr;
  
  	if (!estate->readonly_func)
*************** exec_simple_check_plan(PLpgSQL_expr *exp
*** 5341,5346 ****
--- 5366,5372 ----
  	 */
  	expr->expr_simple_expr = tle->expr;
  	expr->expr_simple_state = NULL;
+ 	expr->expr_simple_in_use = false;
  	expr->expr_simple_lxid = InvalidLocalTransactionId;
  	/* Also stash away the expression result type */
  	expr->expr_simple_type = exprType((Node *) tle->expr);
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 5b174c49b8bcac4658ffd54fc4493e43221533e7..155796be0f5b2d1ad7850f5734fc6363d3c58c15 100644
*** a/src/pl/plpgsql/src/plpgsql.h
--- b/src/pl/plpgsql/src/plpgsql.h
*************** typedef struct PLpgSQL_expr
*** 214,223 ****
  
  	/*
  	 * if expr is simple AND prepared in current transaction,
! 	 * expr_simple_state is valid. Test validity by seeing if expr_simple_lxid
! 	 * matches current LXID.
  	 */
! 	ExprState  *expr_simple_state;
  	LocalTransactionId expr_simple_lxid;
  } PLpgSQL_expr;
  
--- 214,225 ----
  
  	/*
  	 * if expr is simple AND prepared in current transaction,
! 	 * expr_simple_state and expr_simple_in_use are valid. Test validity by
! 	 * seeing if expr_simple_lxid matches current LXID.  (If not,
! 	 * expr_simple_state probably points at garbage!)
  	 */
! 	ExprState  *expr_simple_state;		/* eval tree for expr_simple_expr */
! 	bool		expr_simple_in_use;		/* true if eval tree is active */
  	LocalTransactionId expr_simple_lxid;
  } PLpgSQL_expr;
  
