Run a parsed plpgsql body.
The evaluator has two primitives and everything else is control flow:
SELECT <expr> and take one valueBoth go through the handler this function was called from, which is
what SPI is for PostgreSQL: the nested statement sees the same
transaction, the same temporary tables and the same session. That is
also why pl_exec.c is 9,226 lines and this is not -- most of it is
memory contexts, plan caching and TupleDesc conversion, none of which
we have to reproduce.
Variables reach an embedded statement through params/*plpgsql-vars*,
which the expression translator consults for a bare name that
resolves to no column. A statement that reads one is marked
session-dependent so its plan is not shared; PostgreSQL passes them
as parameters and plans once, which is the better trick and the one
to move to when the translator can take values at Bind.
Run a parsed plpgsql body. The evaluator has two primitives and everything else is control flow: - evaluate an expression -- run `SELECT <expr>` and take one value - run a statement -- hand the source to the query handler Both go through the handler this function was called from, which is what SPI is for PostgreSQL: the nested statement sees the same transaction, the same temporary tables and the same session. That is also why `pl_exec.c` is 9,226 lines and this is not -- most of it is memory contexts, plan caching and TupleDesc conversion, none of which we have to reproduce. Variables reach an embedded statement through `params/*plpgsql-vars*`, which the expression translator consults for a bare name that resolves to no column. A statement that reads one is marked session-dependent so its plan is not shared; PostgreSQL passes them as parameters and plans once, which is the better trick and the one to move to when the translator can take values at Bind.
(run-body handler ast args setof? arg-types)Run a parsed plpgsql body with args bound, and return
{:value v} for a scalar function or {:rows [[…] …]} for a
set-returning one.
args is a seq of [name value] and arg-types the declared type of
each by the same name. An unnamed parameter is reachable as $n,
which is bound under that name too.
The types matter: a statement gives its result back as TEXT, so
without them a := a - 1 turned an integer parameter into the
string "3" and the next comparison against it was nonsense.
Run a parsed plpgsql body with `args` bound, and return
`{:value v}` for a scalar function or `{:rows [[…] …]}` for a
set-returning one.
`args` is a seq of [name value] and `arg-types` the declared type of
each by the same name. An unnamed parameter is reachable as `$n`,
which is bound under that name too.
The types matter: a statement gives its result back as TEXT, so
without them `a := a - 1` turned an integer parameter into the
string "3" and the next comparison against it was nonsense.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |