Skip to main content
Two reference extensions ship in the Rust SDK repository — a minimal function-only example and a complete custom type with arithmetic, ordering, and hashing. Source: examples/ in vsql-rust-sdk

vsql_rot13 — Function-Only Extension

The simplest possible Rust extension: one VDF that takes a STRING and returns a STRING. Usage:

Directory Structure

Implementation

File: src/lib.rs
Key patterns:
  • VDFs receive &[InValue] and return VdfReturn — both are safe Rust enums
  • NULL is a first-class variant on both sides; pattern-match it directly
  • The extension! macro generates the C entry points the server calls at load time
  • func! declares the SQL signature; argument and return types use villagesql::Type::*

Manifest

File: manifest.json

vsql_rational — Custom Type with Arithmetic

A complete custom type: rational numbers stored as (numerator, denominator) in reduced form, with arithmetic functions, ordering, and hashing. Usage:

Binary Storage Format

rational stores 16 bytes (little-endian):
  • Bytes 0–7: numerator (i64)
  • Bytes 8–15: denominator (i64)
Values are always stored in reduced form (GCD = 1) with a positive denominator.

Type-System Functions

File: src/lib.rs The type registers four operations: encode (string → bytes), decode (bytes → string), compare (for ORDER BY), and hash (for indexing).

VDF Implementations

VDFs that take a custom type receive InValue::Custom(&[u8]) and decode the bytes themselves:

Registration

The extension! macro registers both the type and its functions in a single declaration:
Key patterns:
  • villagesql::custom!("name") references a custom type as an argument or return
  • custom_type! registers the type alongside its encode/decode/compare/hash functions
  • default: "0/1" is the intrinsic default — the server calls encode() on this string at type initialization, so it must be a valid value
  • persisted_length must match the byte length encode() returns
  • deterministic: true lets the optimizer fold constant calls

Key Implementation Patterns


Testing

Both examples use MTR (the MySQL Test Runner) just like C++ extensions:
Generate or update expected results with --record.

Next Steps

Creating Extensions in Rust

SDK installation, build, and the extension! macro

Rust Custom Types

Deep dive on encode, decode, compare, and hash

Rust API Reference

InValue, VdfReturn, and the macro surface

Example Source

vsql_rot13 and vsql_rational complete source