Skip to main content

SidPrerequisiteKind

Enum SidPrerequisiteKind 

Source
pub enum SidPrerequisiteKind {
    None,
    SqlInstallable,
    OperatorArtifact,
    Refused,
    EmittedInSchema,
    Undeclared,
}
Expand description

What a platform’s SID prerequisite actually asks of whoever deploys.

The bundle’s prerequisites step has to emit a different shape for each of these, and the deploy script a different behaviour: one runs SQL, one verifies and refuses, one refuses outright, one says there is nothing to do. Sniffing that out of the prose at each call site would put the rule in the generator, the script writer and the runner — three readings of one fact, which is exactly how one derivation becomes two.

The default derives it from what the dialect already says, so a dialect that overrides nothing is still classified correctly and only a platform the derivation cannot reach (Refused, None) has to override.

Variants§

§

None

Nothing to install: the engine’s own hash already IS the canonical number (XXH64 seed 0), reachable from SQL razeri emits.

A positive claim, and therefore never a default. Saying this means razeri has measured that the platform’s builtin returns XXH64 seed 0 — not that nobody has said otherwise. A dialect that has declared nothing gets Undeclared instead, for the same reason DdlRenderer::representable_timestamp_ceiling’s None means no measured ceiling rather than holds everything.

The derivation cannot reach this variant. A dialect claiming it overrides ReplicationRenderer::sid_prerequisite_kind and cites the measurement, as Razeri’s own ClickHouse dialect does.

§

SqlInstallable

Razeri emits statements that install it, and a deploy script can run them unattended: INSTALL/LOAD (DuckDB), CREATE FUNCTION (Snowflake’s JavaScript UDF, Databricks’ Python one).

The test is “can a script finish this with no human on the host”. It is not “is the statement SQL”: CREATE EXTENSION is SQL and only registers a shared object somebody compiled first, which is why PostgreSQL and Citus are OperatorArtifact and not this.

§

OperatorArtifact

An artifact the operator builds and places before any SQL can reference it — MariaDB’s and MySQL’s .so, PostgreSQL’s and Citus’s pg_xxhash. Razeri emits the source or the build recipe as prose; it cannot compile anything, and it will not pretend to.

The deploy path’s obligation here is the prerequisites verb: verify, then refuse — ask the engine for the function and stop in front of schema when it is not there, rather than deploying a warehouse whose keys it cannot compute.

§

Refused

The platform cannot be made to compute razeri’s key from SQL at all, and no artifact an operator drops in changes that.

Redshift is the case: its prerequisites.sql says why. A platform with no CREATE FUNCTION whose client can load a compiled library is not this case — SQLite ships its key function as a library the operator compiles, an OperatorArtifact.

The answer is a named refusal carried in the bundle, checked before any data moves. Never a silent fall-back expression: a number that looks like a key and is not razeri’s writes keys no other deployment can reproduce.

§

EmittedInSchema

Nothing to install here, because razeri’s own key function travels in schema.sql instead — one definition in every namespace whose objects call it, created beside those objects, so a namespace deploys on its own.

BigQuery is the case and the reason is name resolution, not taste: a bare generate_sid('test') is “Function not found: generate_sid; Did you mean generate_uuid?” there — no search path, no session schema, no default dataset inside a procedure body — so every call site must name the dataset the function was created in, and a prerequisites script has no dataset to create it in. The definition therefore rides schema.sql, where the domain’s namespace is known.

It is not None. That variant is the positive claim “the engine’s own hash IS the canonical number”, which is false here: BigQuery has no XXH64 in any spelling and the key is a razeri-owned JavaScript UDF. What the two share is only the deploy behaviour — nothing to run before schema.sql — and sharing a behaviour is not sharing a claim.

§

Undeclared

Razeri has no measured answer for this platform — the honest default, and the one a dialect gets by saying nothing.

§Why this variant exists

A derivation that answered None here would turn “this dialect declared nothing” into the positive claim “its own hash is razeri’s number” — a claim that has been false on real engines. Silence and safety must never read the same, so silence gets its own variant.

§What it means to a deploy path

The same as OperatorArtifact: verify, then refuse. Safe-by-default is the only defensible reading of “razeri does not know” — the contract allows an emitted UDF or a named refusal and explicitly not a local approximation, and proceeding on an unmeasured platform is neither.

A dialect that genuinely needs no prerequisite says so by overriding ReplicationRenderer::sid_prerequisite_kind to None, with its measurement cited.

Trait Implementations§

Source§

impl Clone for SidPrerequisiteKind

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for SidPrerequisiteKind

Source§

impl Debug for SidPrerequisiteKind

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for SidPrerequisiteKind

Source§

impl PartialEq for SidPrerequisiteKind

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for SidPrerequisiteKind

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.