# MySQL Community Design Proposal **Status:** Draft **Roadmap Section:** Extensibility **Primary Contact:** Adam Levin **Email:** [adam@villagesql.com](mailto:adam@villagesql.com) **Company / Organization:** VillageSQL **Role / Team:** Engineering **Additional Authors / Contributors:** VillageSQL Team **Date:** 2026-05-05 **Target Release:** TBD **Related References:** TBD --- ## 1\. High-Level Description ### Executive Summary VillageSQL is an open-source tracking fork that is a drop-in replacement for MySQL. It is built around a stable, versioned extension API and ABI — the VillageSQL Extension Framework (VEF). VEF loads custom SQL types, custom functions, and custom index structures into MySQL without modifying the core engine. Extensions are versioned artifacts: the server and extension negotiate compatibility at load time, and an extension compiled against a given API version loads on any server that implements it. MySQL provides three existing mechanisms for extending server behavior: UDFs, plugins, and components. Each addresses a narrower problem. UDFs support scalar function registration but have a weakly typed interface and carry no binary compatibility guarantee across server versions. Plugins extend predefined subsystems — storage engines, authentication, full-text parsers — but are not general-purpose and require internal server headers with no documented stability guarantee. Components improve on plugins with a service registry but store only a component URI with no version or integrity record, creating the risk of silent drift between what the server expects and what binary is actually loaded. None of the three support custom SQL type registration or custom index structures. We are proposing a shared extension API spec — one that VEF already implements — and asking Oracle to provide an independent implementation. An extension author compiles once against the spec and ships a binary that loads on any conforming server, whether the implementation came from Oracle or VillageSQL. `INSTALL EXTENSION` and `UNINSTALL EXTENSION` are the SQL interface. Packaging format and distribution-specific behavior remain outside the boundary. ### User / Developer Stories - **Extension author**: compile once, ship a binary that loads on any conforming server. - **Contributor**: participate in defining a versioned API that evolves without breaking existing extensions. - **User / administrator**: run `INSTALL EXTENSION` without worrying about version or distribution compatibility. ### Scope **In Scope** - A versioned C-compatible header set defining the server–extension boundary - A versioning and compatibility declaration mechanism (extension declares minimum API version; server rejects incompatible extensions at load time) - An initial set of extension capability classes, defined in Section 4, covering the most common extension patterns; the API is designed so additional capability classes can be added in future versions without breaking existing extensions - `INSTALL EXTENSION` and `UNINSTALL EXTENSION` SQL statements for managing extensions - A conformance test suite that distributions can run to verify API compliance **Out of Scope / Limitations** - Packaging format (`.so`, `.veb`, or any bundle format) — left to distributions - Full replication protocol for extension-defined operations — deferred to a follow-on proposal; see Compatibility and Behavior Change for the minimum expectation - This proposal does not require or assume changes to the existing MySQL plugin infrastructure ### References - MySQL Plugin API documentation (dev.mysql.com) - VillageSQL public roadmap (villagesql.com) --- ## 2\. Requirements ### Functional Requirements - FR1. Extensions MUST compile against a versioned header set and load without recompilation on any server that implements the same API version. The API version is independent of the MySQL server version — an extension targeting Extension API v1 loads on any MySQL-compatible server that implements Extension API v1, regardless of the server's MySQL version. - FR2. The API MUST define a versioned capability model. Each capability class is part of a defined API version. New capability classes MUST be addable in future API versions without breaking extensions compiled against earlier versions. - FR3. The API MUST provide a versioning and compatibility declaration mechanism. A server MUST reject an extension that declares a minimum API version higher than the server supports. - FR4. The extension entry point MUST be expressible in C to maximize cross-compiler and cross-toolchain compatibility. - FR5. A conforming extension MUST load on any MySQL-compatible distribution that implements the same API version, without recompilation or modification — regardless of which distribution it was originally compiled against. ### Non-Functional Requirements - NFR1. The API MUST be implementable by a distribution without forking or modifying existing MySQL plugin infrastructure. - NFR2. The API header set SHOULD be self-contained — no internal MySQL headers required to build an extension. - NFR3. The versioning mechanism SHOULD allow an extension to declare compatibility with a range of API versions, not just a single pinned version. --- ## 3\. Impact Checklist - [x] New extension/plugin interface - [x] New internal server APIs (server-side implementation of the extension boundary) - [x] Observability (extension load/unload events, version negotiation results) - [x] SQL syntax changes — `INSTALL EXTENSION`, `UNINSTALL EXTENSION` - [x] Replication — minimum expectation defined (see Compatibility and Behavior Change); full protocol deferred - [ ] Storage engine — affected only if a distribution chooses to support custom type storage; not a required part of this proposal --- ## 4\. High-Level Specification ### Summary of the Approach VEF establishes a narrow, stable boundary between the server and the extension. The extension author compiles against a versioned header set. The server exposes a small set of function pointers the extension can call (memory allocation, result writing, error reporting). The extension exposes a single entry point that returns a descriptor: which capabilities it registers and what API version it was compiled against. The server performs version negotiation at load time against the API version, not the MySQL server version. If the extension's declared minimum API version is within the range the server supports, the extension loads. If not, the server rejects it with a version mismatch error that names both versions — enough information to diagnose the incompatibility without reading source. Extensions are managed via `INSTALL EXTENSION` and `UNINSTALL EXTENSION` statements. Packaging format and distribution-specific behavior remain outside the boundary. ### User Interface Two new SQL statements: `INSTALL EXTENSION` loads an extension by name, triggers version negotiation, and registers its capabilities with the server. `UNINSTALL EXTENSION` unloads it and removes its registered capabilities. Both are modeled after the existing `INSTALL PLUGIN` / `UNINSTALL PLUGIN` convention. Version negotiation results are surfaced in error messages when load fails. ### Configuration / Knobs - New system variable: server-reported API version (read-only, diagnostic). - No new configuration clauses or command-line options. ### New Statements See User Interface above. ### Observability - Server error log entry at extension load time: extension name, declared API version, server API version, load result (success or rejection reason). - A system table or status variable listing currently loaded extensions and their declared API versions. ### User Procedure Author compiles against the versioned header set and ships the artifact. DBA runs `INSTALL EXTENSION 'name'`. Server negotiates version and registers capabilities. Extension is available in SQL. ### Security Context - Extensions execute in-process. The server must treat extension code as trusted; this proposal does not change that assumption. - `INSTALL EXTENSION` SHOULD require a privilege (e.g., `SUPER` or a purpose-built `INSTALL_EXTENSION` privilege). ### Compatibility and Behavior Change - The existing MySQL plugin API and UDF API are unaffected. The extension API is a parallel, independent interface. - No behavior change for existing MySQL installations that do not adopt the API. - Distributions that adopt the API must commit to not breaking extensions compiled against an older (but still supported) API version within the version range they advertise. - Replication minimum expectation: an extension must be installed on all nodes in a replication topology that use tables or statements depending on it. The server SHOULD warn or error if a replicated statement references an extension that is not installed on the replica. Full replication protocol is deferred to a follow-on proposal. --- ## 5\. Low-Level Design ### Block Diagram ``` Extension author | | compiles against v [ Versioned API headers ] | | produces v [ Extension artifact (.so / bundle) ] | | INSTALL EXTENSION v [ MySQL-compatible server ] | |-- version negotiation ---> accept / reject | |-- registers capabilities into server's extension registry | v [ SQL runtime: extension capabilities available to queries ] ``` ### Interface Specification The public API surface consists of three categories. The capability descriptors in categories 2 and 3 represent the initial capability set; additional descriptor types are added in future API versions. 1. **Extension entry point** — a single exported C symbol returning a descriptor struct. The descriptor names the extension, declares the minimum and maximum API versions it supports, and provides a list of capability descriptors to register. 2. **Server-provided callbacks** — a small set of function pointers the server populates and passes to the extension at load time, covering memory allocation, result writing, and error reporting. 3. **Capability descriptors** — per-capability structs the extension populates to describe what it registers. The initial set covers custom functions and custom types; the descriptor format is versioned so new capability classes can be added without changing the entry point contract. No internal MySQL headers are required to implement an extension against this interface. ### Design / Implementation Steps 1. Define and publish versioned header set (v1). 2. Implement server-side entry point loader and version negotiation. 3. Implement `INSTALL EXTENSION` / `UNINSTALL EXTENSION` statements. 4. Implement initial capability class registrations (defined in the v1 header set). 5. Implement observability: error log entries, status variable for loaded extensions. 6. Publish conformance test suite for distributions. --- ## 6\. QA Notes - Conformance test suite: reference extensions covering each capability class and each declared API version. Distributions run this suite to verify compliance. - Version negotiation tested at boundaries: N-1 (reject), N (accept), N+1 (accept if range declared). Load failure must produce an error naming both the extension's declared version and the server's supported range.