---------- * exec_eval_simple_expr - Evaluate a simple expression returning * a Datum by directly calling ExecEvalExpr(). * * If successful, store results into *result, *isNull, *rettype, *rettypmod * 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 re
| 5962 | * ---------- |
| 5963 | */ |
| 5964 | static bool |
| 5965 | exec_eval_simple_expr(PLpgSQL_execstate *estate, |
| 5966 | PLpgSQL_expr *expr, |
| 5967 | Datum *result, |
| 5968 | bool *isNull, |
| 5969 | Oid *rettype, |
| 5970 | int32 *rettypmod) |
| 5971 | { |
| 5972 | ExprContext *econtext = estate->eval_econtext; |
| 5973 | LocalTransactionId curlxid = MyProc->lxid; |
| 5974 | ParamListInfo paramLI; |
| 5975 | void *save_setup_arg; |
| 5976 | bool need_snapshot; |
| 5977 | MemoryContext oldcontext; |
| 5978 | |
| 5979 | /* |
| 5980 | * Forget it if expression wasn't simple before. |
| 5981 | */ |
| 5982 | if (expr->expr_simple_expr == NULL) |
| 5983 | return false; |
| 5984 | |
| 5985 | /* |
| 5986 | * If expression is in use in current xact, don't touch it. |
| 5987 | */ |
| 5988 | if (unlikely(expr->expr_simple_in_use) && |
| 5989 | expr->expr_simple_lxid == curlxid) |
| 5990 | return false; |
| 5991 | |
| 5992 | /* |
| 5993 | * Ensure that there's a portal-level snapshot, in case this simple |
| 5994 | * expression is the first thing evaluated after a COMMIT or ROLLBACK. |
| 5995 | * We'd have to do this anyway before executing the expression, so we |
| 5996 | * might as well do it now to ensure that any possible replanning doesn't |
| 5997 | * need to take a new snapshot. |
| 5998 | */ |
| 5999 | EnsurePortalSnapshotExists(); |
| 6000 | |
| 6001 | /* |
| 6002 | * Check to see if the cached plan has been invalidated. If not, and this |
| 6003 | * is the first use in the current transaction, save a plan refcount in |
| 6004 | * the simple-expression resowner. |
| 6005 | */ |
| 6006 | if (likely(CachedPlanIsSimplyValid(expr->expr_simple_plansource, |
| 6007 | expr->expr_simple_plan, |
| 6008 | (expr->expr_simple_plan_lxid != curlxid ? |
| 6009 | estate->simple_eval_resowner : NULL)))) |
| 6010 | { |
| 6011 | /* |
| 6012 | * It's still good, so just remember that we have a refcount on the |
| 6013 | * plan in the current transaction. (If we already had one, this |
| 6014 | * assignment is a no-op.) |
| 6015 | */ |
| 6016 | expr->expr_simple_plan_lxid = curlxid; |
| 6017 | } |
| 6018 | else |
| 6019 | { |
| 6020 | /* Need to replan */ |
| 6021 | CachedPlan *cplan; |
no test coverage detected