villagesql crate API. For the getting started tutorial, see Creating Extensions in Rust. For custom types, see Custom Types in Rust.
InValue
InValue is the enum the server passes for each function argument. Your function receives args: &[InValue] and must check each argument before using its value.
Always match on
Null explicitly. Calling .unwrap() or pattern-matching only the value variants is a bug — SQL NULL is a normal input, not an error.
VdfReturn
VdfReturn is what your function returns to the server. Construct it with one of the associated functions:
Warning vs error:
Use
warning for user-input validation failures where continuing with the rest of the result set makes sense. In strict mode, MySQL promotes warnings to errors on INSERT and UPDATE. Use error for conditions where proceeding is unsafe — corrupt stored data, internal invariant violations. A fatal error aborts the entire statement.
extension! macro
extension! generates the VEF entry points the server calls when loading your VEB file. It must appear exactly once in the crate.
types:; a type-only extension omits funcs:. An empty extension! block (no funcs, no types) is valid but produces an extension that does nothing.
func! macro
func! declares a SQL-callable function. Four forms (no parameters, buffer_size only, deterministic only, both):
The
buffer_size parameter requires the villagesql crate 0.0.2 or
later. The current crates.io release
(0.0.1) doesn’t expose it — until 0.0.2 ships, use the forms without
buffer_size.
Type constants for use in
func!:
custom_type! macro
custom_type! registers a new column type. type_name, persisted_length, max_decode_buffer_length, encode, decode, and compare are required. hash and default are optional but recommended.
The
default field is not a column default value — it’s a startup probe. The server calls encode(default) when loading the extension to verify the callback works. If encode returns Err for the default, the extension fails to load.
custom! macro
villagesql::custom!("type_name") references a custom type by name in a func! declaration:
villagesql::Type::* would appear in a parameter list or return type position. The string must match the type_name declared in the corresponding custom_type!.
manifest.json fields
Every extension needs amanifest.json alongside its Cargo.toml:
name validation rules: must start with a letter, end with a letter or digit, max 64 characters. An invalid manifest causes INSTALL EXTENSION to fail.
