Liking cljdoc? Tell your friends :D

datahike.pg.plpgsql.exec

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 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.
raw docstring

datahike.pg.plpgsql.parse

Parse a plpgsql function body into an AST.

pl_gram.y is the specification. What that grammar actually does -- and what this does -- is parse the statement structure and hand every embedded expression and query to the SQL parser untouched. plpgsql has no expression grammar of its own: IF a > b THEN finds the THEN and gives a > b to the SQL layer as SELECT a > b. So the job here is to find where each embedded fragment ends, and to keep its SOURCE, which the executor later runs through the ordinary statement path.

Everything pl_gram.y accepts is parsed, including the constructs the executor does not implement. That is deliberate: CREATE FUNCTION walks the AST and refuses a body that uses one, naming it, so an unimplemented construct is a clean 0A000 at definition time rather than a wrong answer at call time.

The tokenizer is the SQL classifier's, so a keyword inside a string, a comment, a dollar-quoted body or a quoted identifier is not a keyword.

Parse a plpgsql function body into an AST.

`pl_gram.y` is the specification. What that grammar actually does --
and what this does -- is parse the *statement structure* and hand
every embedded expression and query to the SQL parser untouched.
plpgsql has no expression grammar of its own: `IF a > b THEN` finds
the `THEN` and gives `a > b` to the SQL layer as `SELECT a > b`. So
the job here is to find where each embedded fragment ends, and to
keep its SOURCE, which the executor later runs through the ordinary
statement path.

Everything `pl_gram.y` accepts is parsed, including the constructs
the executor does not implement. That is deliberate: `CREATE
FUNCTION` walks the AST and refuses a body that uses one, naming it,
so an unimplemented construct is a clean 0A000 at definition time
rather than a wrong answer at call time.

The tokenizer is the SQL classifier's, so a keyword inside a string,
a comment, a dollar-quoted body or a quoted identifier is not a
keyword.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close