Skip to main content

Module routine_render

Module routine_render 

Source
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.