在PL/pgSQL语言中,执行任何SQL都需要通过SPI调用SQL层解析执行,例如在SQL层执行表达式的入口:
static bool
exec_eval_simple_expr(PLpgSQL_execstate *estate,
PLpgSQL_expr *expr,
Datum *result,
bool *isNull,
Oid *rettype,
int32 *rettypmod)
{
ExprContext *econtext = estate->eval_econtext;
...
...
*result = ExecEvalExpr(expr->expr_simple_state,
econtext,
isNull);
...
...
表达式的运行时、内存都是在ExprContext中存放的,所以PL在调用任何函数前都会提前申请好ExprContext内存,执行表达式时可以直接使用。
使用后都会调用exec_eval_cleanup把eval_econtext的内存reset掉,避免影响后面执行的表达式。
在SQL层,ExprContext内存往往是挂在EState(SQL层的运行时)下的,PL也仿照SQL层做了一些事情,下面展开讲讲。
PL内执行commit时
多层函数时PL内执行commit