Expand description
§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 this 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:
SqlRenderer— core SQL rendering (the four required methods)ExpressionRenderer— expressions, with ANSI defaultsDdlRenderer— DDL, with ANSI defaultsDmlRenderer— DML, with ANSI defaultsProcedureRenderer— stored procedures and functionsFormulaRenderer— formulas, with ANSI defaultsTaskRenderer— scheduled tasksReplicationRenderer— data extraction, loading and key-function deploymentStorageRenderer— partitioning, compression and index strategyDialectCapabilities— what the platform’s SQL can and cannot do
The vocabulary those traits speak: DataType and DataTypeRef, the
storage_strategy::StoragePlan a StorageRenderer translates, the
StoragePlatform a storage plugin names, and DialectFamily, the
platform’s own identity.
The spelling a source gives a day — date_format. One import
arrives with 1/1/2015 in one column and 2015-01-01T00:00:00Z in the
next; the design states the spelling, this crate reads it once into a list
of directives, and each engine translates that list into its own pattern
language through ExpressionRenderer::render_parse_datetime. A directive
an engine cannot spell is refused by name.
The fan-out an engine states — flatten. One row holding an array
becomes one row per element, and every engine spells that differently, so
the dialect answers with the whole shape rather than filling in a template.
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 and ScalarFunctionForm, the
routine grammars it speaks, MergeShape, how it upserts, and
EvolutionAnswers, what it keeps when a table that already holds rows
changes shape.
The surrogate key’s composition — sid turns a SidSpelling into
the key expression an engine runs. It is here rather than in the product
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 this repository can check.
The named routine grammars, spelled — routine_render. A dialect
whose engine has stored procedures in a grammar of its own renders the whole
CREATE itself, and “PL/pgSQL with one tweak” used to mean writing the
whole thing from nothing. These three functions write out the grammar a
dialect is nearly the same as, so it can start there and say what differs.
§What is deliberately not in here
Razeri’s design model, and the renderers that turn it into Razeri’s own output. A plugin says what its engine spells; Razeri composes. That division is why one contract crate can be open while the product is not.
The routine grammars are the one thing on both sides of that line, and they are here because they belong to the engines rather than to Razeri’s design: a plugin author who cannot read the grammar next to theirs has to guess at it.
§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_proceduretakes the companion table a load sets rows aside in, so one call to a retention procedure reaches both tables.ExpressionRenderer::render_parse_datetimerenders the parse of a value the source spells its own way into a date or a timestamp.
Re-exports§
pub use data_type::DataType;pub use data_type::DataTypeRef;pub use date_format::DateFormat;pub use date_format::DateFormatError;pub use date_format::FormatDirective;pub use date_format::FormatPart;pub use dialect_family::DialectFamily;pub use flatten::Flatten;pub use flatten::FlattenField;pub use flatten::FlattenRequest;pub use procedure_log_level::ProcedureLogLevel;pub use routine_render::render_procedure_as;pub use routine_render::render_scalar_function_as;pub use routine_render::render_table_function_as;pub use sid::sid_expression;pub use storage_platform::StoragePlatform;pub use agnostic::*;pub use capabilities::*;pub use constraint_enforcement::*;pub use evolution::*;pub use formula_renderer::*;pub use merge_shape::*;pub use renderer::*;pub use replication::*;pub use routine_form::*;pub use routine_spec::*;pub use sid_spelling::*;pub use storage_renderer::*;pub use task_renderer::*;
Modules§
- agnostic
- Agnostic dialect and ANSI data-type rendering.
- capabilities
- Boolean capability flags with conservative defaults.
- constraint_
enforcement - Whether this engine actually checks the constraints it accepts — the dialect’s answer, and the one place the rendered DDL and the docs read it from.
- data_
type - Generic data types for cross-database compatibility.
- date_
format - How a source spells a day — the format a design states, read once and handed to every engine as a list rather than as text.
- dialect_
family - Dialect Family Definitions
- evolution
- Changing a table that already holds rows — what this engine keeps through such a change, and the statement it takes to make one.
- flatten
- One row holding an array becomes one row per element — the vocabulary an engine answers a fan-out in.
- formula_
renderer - Formula-level rendering extensions with ANSI defaults.
- merge_
shape - How this engine performs an upsert — a shape the dialect describes, not a switch it flips.
- procedure_
log_ level - How loud a message a procedure body writes is.
- renderer
- Layered rendering traits for SQL generation.
- replication
- Replication rendering traits with ANSI defaults.
- routine_
form - Which routine grammar this engine speaks — the dialect’s answer, not a core crate’s guess about its name.
- routine_
render - The named routine grammars, rendered where a plugin can reach them.
- routine_
spec - The routine Razeri composed, handed to a dialect that spells its own grammar.
- sid
- The one derivation of a surrogate key, composed from the vocabulary a dialect states.
- sid_
spelling - How this engine spells a surrogate key — the one thing about the key a dialect decides.
- storage_
platform - Storage platform enumeration for raw file management.
- storage_
renderer - Storage rendering trait for partition, compression, and index strategies.
- storage_
strategy - Agnostic storage strategy types: partition, compression, index.
- task_
renderer - Task and schedule rendering extensions.