razeri-plugin-contract 0.5.0

The dialect contract Razeri plugins are written against — rendering traits, data types, platform identity
Documentation

razeri-plugin-contract

The contract a Razeri dialect plugin is written against.

This crate and razeri-plugin-api are the two open crates in Razeri's workspace. Everything a plugin author needs in order to describe and render a database platform lives here; nothing else does. It depends on serde and on nothing else at all, which is what lets a plugin be built, published and consumed outside Razeri's repository.

What is in here

The rendering hierarchy — ten traits, layered so that a new dialect implements four required methods and inherits ANSI-standard behaviour for the rest:

Trait What it renders
SqlRenderer Core SQL — the four required methods
ExpressionRenderer Expressions, with ANSI defaults
DdlRenderer DDL, with ANSI defaults
DmlRenderer DML, with ANSI defaults
ProcedureRenderer Stored procedures and functions
FormulaRenderer Formulas, with ANSI defaults
TaskRenderer Scheduled tasks
ReplicationRenderer Data extraction, loading and key-function deployment
StorageRenderer Partitioning, compression and index strategy
DialectCapabilities What the platform's SQL can and cannot do

The vocabulary those traits speak: DataType and DataTypeRef, the StoragePlan a StorageRenderer translates, the StoragePlatform a storage plugin names, and DialectFamily, the platform's own identity.

The decisions a dialect states rather than a core crate deciding for it — starting with SidSpelling, how this engine spells a surrogate key, and continuing with ProcedureForm, ScalarFunctionForm and TableFunctionForm, the routine grammars it speaks. Each of the three carries a Custom arm for a grammar Razeri does not know: your dialect names it and renders the routine itself, from the RoutineSpec Razeri hands over.

The spelling a source gives a day — date_format. One import arrives writing 1/1/2015 in one column and 2015-01-01T00:00:00Z in the next, and no two engines read either of them the same way. The design states the spelling, this crate reads it once into a list of directives, and ExpressionRenderer::render_parse_datetime is where your dialect translates that list into whatever pattern language your engine has. A directive your engine cannot say is a refusal naming it, never a guess.

The fan-out an engine states — flatten. One row holding an array becomes one row per element, and no two engine families spell that the same way, so the dialect's render_flatten answers with the whole shape — the FROM item, the ordinal and one expression per field — rather than filling in a template. The ordinal it returns counts from one on every engine, because the element's surrogate key is derived from its position.

The surrogate key's composition — sid::sid_expression turns a SidSpelling into the key expression an engine runs. It is here because a dialect author who cannot render their own key expression cannot run it either, and "the same key on every engine" is then a claim nobody outside Razeri's repository can check.

AnsiDialect is a complete worked implementation of the required methods, and render_data_type_ansi is the ANSI type mapping to start from.

How this crate is versioned

While the major version is zero:

  • a change to a trait's method set bumps the minor version — a method added, removed or renamed, whether or not it carries a default body;
  • documentation and fixes bump the patch version.

The rule is about who decides when a plugin's behaviour changes. Cargo flows a patch release to every plugin pinned at the minor the next time it builds, and flows a minor release to nobody. A defaulted method costs an existing plugin no line of code, and it still changes what that plugin says: an engine that has not implemented the new method now answers the default, and its users meet whatever Razeri does with that answer — a refusal they had never seen, arriving because somebody else released. So a new method is opted into, and the plugin author chooses the day.

This is stricter than semantic versioning requires of a zero-major crate, deliberately: the looser reading saves a version number and spends a plugin author's afternoon.

What 0.5.0 adds to the method set

  • StorageRenderer::render_partition_retain_procedure takes the companion table a load sets rows aside in, so one call to a retention procedure reaches both tables.
  • ExpressionRenderer::render_parse_datetime renders the parse of a value the source spells its own way into a date or a timestamp. Leave it alone and your engine states nothing: a design naming a spelling is refused, with your engine named.

What is deliberately not in here

Razeri's design model and every renderer that produces Razeri's own output. A plugin says what its engine spells; Razeri composes.

License

Dual-licensed under MIT or Apache 2.0, at your option. Plugins belong to their authors.

Security

Report a vulnerability through GitHub's private vulnerability reporting on the Razeri repository — see its security policy.