Expand description
The named routine grammars, spelled.
A dialect whose engine has a routine in a grammar Razeri does not carry
renders the whole CREATE itself. These three functions write out the
grammars Razeri does carry, from the same
RoutineSpec a dialect receives, so a
grammar that is “PL/pgSQL with one tweak” starts from PL/pgSQL and says
what differs rather than being written from nothing.
The named routine grammars, rendered where a plugin can reach them.
A dialect states which grammar its engine speaks through
ProcedureForm,
ScalarFunctionForm and
TableFunctionForm. Where the answer is one of
the named grammars, Razeri spells it. Where the answer is Custom, the
dialect spells the whole CREATE itself — and a dialect whose grammar is
“PL/pgSQL with one tweak” should not have to write the whole thing from
nothing, with no way to see, reuse or diff against the grammar it is almost
the same as.
These three functions are that grammar, addressable:
use razeri_plugin_contract::routine_render::render_procedure_as;
use razeri_plugin_contract::{ProcedureForm, RoutineSpec};
// Start from the neighbouring grammar, then say what is different.
let near = render_procedure_as(ProcedureForm::PlPgSql, routine);
Some(near.replace("LANGUAGE plpgsql", "LANGUAGE plpgsql_with_one_tweak"))§What these render from, and what that means
They render from a RoutineSpec — the routine as a Custom dialect
receives it: names, parameters with their types already spelled, local
declarations, what it returns, the body’s statements, the comment. That is
everything a CREATE needs, and it is deliberately not the design Razeri
composed it from.
So the output is the form’s grammar around the statements it is given. A statement’s own spelling was decided before the spec was built: where Razeri composes a routine from its own design it spells each statement for the engine first, and where a caller builds a spec by hand the statements are whatever the caller wrote. Neither is this module’s business, and that is why one function can answer for every form.
§Which forms answer with SQL
Every form that names a SQL grammar. Two ProcedureForm variants do not
name one: ClickHouse deploys a procedure as an executable program with an
XML declaration beside it, and Databricks as a Python function — neither is
a CREATE any engine parses, and neither can be spelled from a spec. Both
answer here with the agnostic form under a comment saying so, because a
wrong CREATE is worse than a plain sentence.
Custom answers with the agnostic form too, under a comment naming the
grammar. It is not an error to ask: a dialect that wants a neutral starting
point, or a fallback branch that reaches this with its own form, gets
something to read rather than a panic.
Unsupported answers with the dialect’s own words in a comment, and never a
statement — the same sentence, in the same place, that Razeri puts where the
routine would have been.
Functions§
- render_
procedure_ as - Spell this procedure in a named grammar.
- render_
scalar_ function_ as - Spell this scalar function in a named grammar.
- render_
table_ function_ as - Spell this table-valued function in a named grammar.