Skip to content

Common interface implementation matrix ​

Reference: Common interface v1, machine specification, and generated model. Reproduction commands and check coverage are in the verification guide.

Local verification: 36 conformance vectors × Go, PHP, Rust, TypeScript, and Python × MySQL, PostgreSQL, and SQLite produce the same statements, binds, and results. The generated interface, native symbol, and record checks run from make interface-check.

Rust ORM mapping ​

The generated models use the following public Rust API directly; there is no intermediate query or model layer.

Specification callRust API and behavior
Engine selection and connectionDb::connect(dsn, pool_size, Config) selects MySQL, PostgreSQL, or SQLite from the DSN and creates the bounded pool without any registered set; Db::connect_schema(dsn, &SCHEMA, pool_size, Config), which the generated model::connect calls, also registers the set of the generated models.
Schema hash checkA generated Schema::new(manifest_text, manifest_hash) validates the embedded manifest text; the engine rejects a request whose hash differs with SCHEMA_HASH_MISMATCH.
Schema installation and inspectiondb.utils().schema().install(&model::SCHEMA) installs the set, verifies the database and registers the set on the connection; db.utils().schema().register(&model::SCHEMA) registers the set without reading the database; exists, installed, and empty inspect the selected database. Audit directives in the manifest are installed with the audit tables and triggers.
Transaction isolation, read-only, timeout, retry, and auditdb.transaction(callback).isolation(Isolation::...).read_only().timeout_ms(ms).retry(count) applies the declared options; retry(0) runs the callback once. Db::transaction_once(callback) preserves the callback error and does not retry. audit(values) on each of the three transaction builders inserts the audit record of the unit of work from the values of Config::audit_source.
CancellationDropping a statement or transaction future closes its checked-out connection so the server operation is canceled or rolled back before that slot is reused; driver cancellation maps to CANCELED.
Encrypted columnsConfig::aes_version, Config::aes_keys, Config::blind_index_key, and db.utils().aes() provide key validation, encrypted writes, blind indexes, status, and rotation for generated encrypted columns.

PostgreSQL, MySQL, and SQLite cases exercise these calls, and the pooler case uses the same generated models through a one-slot PgBouncer connection.

InterfaceImplementation and verification
IF-01, IF-18, IF-32Each client plans requests in its own process with a port of the same planner and checks the schema hash of its models. The shared interface specifies equal SQL and binds from the six declared implementations—Go, PHP, PHP extension, Rust, TypeScript, and Python. tests/interfaces/check compares 20 request records field by field for Go, PHP, Rust, TypeScript, and Python; PHP extension declarations are checked against their own declared surface, and remaining native planner evidence stays open.
IF-02Column values keep their logical type. The Go TestConnectionsUseUTC and the equivalent PHP, TypeScript, Rust and Python cases (Python connection_utc.py) check that date and time values are written and read in UTC on SQLite and on MySQL and PostgreSQL servers whose zone is KST, including SQLite string datetime comparisons in the stored six-digit form. Rust generated models use typed NaiveDateTime values and cover the same database time behavior in integration cases
IF-03 ~ IF-08Generated models store the chain state in one core object. The conditions_connectors, conditions_group, expression_forms, conditions_values, joins, and errors vectors check connectors, groups, negated groups, value shapes, join placement, and invalid chains
IF-09 ~ IF-1223 model methods are fixed per language: the generated Go models, the PHP, TypeScript, and Python base classes, and the Rust polyspec-orm-build template. terminal_by and terminal_reuse check terminals and the reuse of one model
IF-13 ~ IF-17Db.connect, Db.transaction, Db.utils, Utils.lock, SchemaUtils.install, and the AES utilities are fixed per language. The transactions vector and the client transaction tests check savepoints, row locks, named locks, and local values
IF-19, IF-20The relations, relation_empty, and subqueries vectors check relation statements and assembly. TestBindLimitSplitting checks the Go split of large IN lists on three databases; PHP, Rust, TypeScript, and Python retain the common planner specification and their client suites check the resulting relation and subquery paths
IF-21 ~ IF-24The write_cycle, now_defaults, creates_and_save, delete_recursive, and restore vectors check dirty writes, clock defaults, upserts, optimistic updates, recursive deletes, and the restore of a soft-deleted row
IF-25 ~ IF-27The owner rules fix the five Page fields and the four AESRotationStatus fields in every language. The client model tests check keyed collections and pages
IF-28 ~ IF-3180 codec vectors, the AES vectors, and the aes_values, aes_status, get_query, and errors vectors check codecs, key versions, masked binds, and error codes
IF-33The manifest generates the component diagram. make interface-check checks the diagram, the symbol snapshots, and the source mutations
IF-34PHP and TypeScript resolve only names that follow the chain rules; the Go and Rust generators reject other names before the build

Structure checks compare the common methods and stored fields first, then report missing, added, and changed native declarations. A SHA-256 value of each symbol list is fixed in contracts/interfaces.json; changing declarations without updating the specification fails. owners restricts the fields of Page and AESRotationStatus, so updating only the symbol list cannot add a state field to them. Language-version syntax such as PHP's default readonly setter form is normalized; explicit access changes remain visible. Seven source-change counterexamples per language are checked.

Planner ownership ​

ClientPlanner and generated model ownerExecutable owner testsDependent-part and shared checks
Gopackages/go/engine/* is called directly by packages/go/orm; generated models are under packages/go/modelpackages/go/orm/*_test.go, packages/go/model/*_test.gotests/conformance/runner.go, tests/interfaces/check
PHPpackages/php/src plans and executes through PDO; generated models are under packages/php/genpackages/php/tests/*.phppackages/php/testing/conformance/runner.php, packages/php/testing/interfaces/php.php
Rustpackages/rust/orm plans and executes through sqlx; polyspec-orm-build generates modelspackages/rust/tests/src, packages/rust/orm/src/*_test.rstests/conformance/runner_rust.rs, packages/rust/testing/interfaces
TypeScriptpackages/ts/src plans and executes through native drivers; generated models are under packages/ts/src/modelspackages/ts/testspackages/ts/testing/conformance/runner_typescript.mts, packages/ts/testing/interfaces/typescript.mts

Each owner test is kept in its client directory. An implementation-internal test checks that implementation's own structure; the shared interface has no counterpart. Conformance compares outputs from the six declared implementations—Go, PHP, PHP extension, Rust, TypeScript, and Python—and does not replace owner tests; tests/interfaces/check verifies the shared declarations and generated artifacts.

These results verify the listed interfaces and scenarios. They do not prove equivalence of every function body or every possible input. Overall progress is tracked in the checklist.

MIT License · Go / PHP / Rust / TypeScript