Skip to main content

Crate razeri_plugin_contract

Crate razeri_plugin_contract 

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

  1. SqlRenderer — core SQL rendering (the four required methods)
  2. ExpressionRenderer — expressions, with ANSI defaults
  3. DdlRenderer — DDL, with ANSI defaults
  4. DmlRenderer — DML, with ANSI defaults
  5. ProcedureRenderer — stored procedures and functions
  6. FormulaRenderer — formulas, with ANSI defaults
  7. TaskRenderer — scheduled tasks
  8. ReplicationRenderer — data extraction, loading and key-function deployment
  9. StorageRenderer — partitioning, compression and index strategy
  10. DialectCapabilities — 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 way a source writes an amount — number_format. A file writes a price $2,899.99 , where the symbol, the thousands mark and the space around it are not part of the number. The design states the picture, this crate reads it once into the marks that are not part of the value, and each engine takes those marks out and converts what is left through ExpressionRenderer::render_parse_number. An engine that states nothing is refused by name rather than guessed for.

The questions asked of a warehouse that is already there — SqlRenderer::render_catalog_columns_query and SqlRenderer::render_catalog_object_times_query. A design says what would be built; how much of a running warehouse was built is a question only that warehouse answers, so each engine spells the two queries that ask it and names the schemas a whole-warehouse scan passes over through SqlRenderer::catalog_system_schemas. None is a complete answer to either query: an engine with no catalog to read is named rather than reported as an empty warehouse.

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

§What 0.6.0 adds to the method set

Beside the method set, sid::normalize_trim is now public: the TRIM in an engine’s own spelling, which both the canonical normalization and the reading of a written amount start from.

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 number_format::Negatives;
pub use number_format::NumberFormat;
pub use number_format::NumberFormatError;
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.
number_format
How a source writes an amount — the picture a design states, read once and handed to every engine as a small set of facts rather than as text.
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.