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 the one platform
the derivation cannot reach (SQLite) 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 — SQL Server’s CLR assembly, 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.
SQLite is the case and, so far, the only one: a standalone sqlite3
has no CREATE FUNCTION in its SQL surface, so there is no statement to
emit and no library to load. Razeri-driven SQLite can register a
function through sqlite3_create_function(), which is a C API, not SQL —
so the bundle’s razeri-free operator genuinely cannot get there from
here.
The answer is a named refusal carried in the bundle, checked before
any data moves. Never a silent fall-back expression — and the fall-back is
not hypothetical or historical: SidSpelling’s sqlite arm
still renders ABS(UNICODE(x)), the code point of the input’s first
character. That is not a weak hash; it is not a hash.
The refusal is what stops it reaching a warehouse; the expression itself
is still what that arm would emit.
EmittedInSchema
Nothing to install here, because razeri’s own key function travels in
schema.sql instead — one definition per domain, created in the
domain’s own namespace.
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
impl Clone for SidPrerequisiteKind
Source§fn clone(&self) -> SidPrerequisiteKind
fn clone(&self) -> SidPrerequisiteKind
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more