Repository navigation
v0.2.0
OxideR-Query v0.2.0
PostgreSQL can now execute, not only render.
What changed
PostgresDb, behind the postgres feature. The builder always targeted three dialects while only SQLite could run a statement, so a Postgres user rendered here and then bound the (sql, params) pair themselves. That gap is closed:
oxider-query-exec = { git = "...", tag = "v0.2.0", features = ["postgres"] }let db = PostgresDb::connect("postgres://...").await?;
let adults: Vec<User> = db
.fetch_all(User::query().filter(User::age.ge(18)))
.await?;Every method is the same as SQLite's. Pointing at the other database is a change of the handle's type and nothing else, which is what the Backend trait existed to make true.
A temporal-encoding defect, found by porting. Value stores dates, times and timestamps as text, because the AST must not depend on a date library. SQLite accepts that, since it types a column by the value it is handed. PostgreSQL carries a type OID per bound parameter and refuses:
ERROR 42804: column "on_day" is of type date but expression is of type text
The Postgres backend parses temporals back into chrono types before binding. The formats were private to the writing side; they are public as oxider_query_core::formats now, so writing and reading share one definition instead of two that can drift apart.
DATE_TIME_UTC changed shape. It wrote a literal +00:00, which formats correctly but cannot be parsed back, because chrono will not read an offset that is not a format specifier. It is %:z now: identical output for a UTC instant, and parseable. This matters most on a TIMESTAMPTZ column, where text is rejected outright but a naive value would have been accepted and silently reinterpreted in the session's own time zone.
Still true from v0.1.0
The builder targets PostgreSQL, MySQL and SQLite. Execution covers PostgreSQL and SQLite; schema codegen is SQLite only. On MySQL you render here and bind with your own driver.
Pre-1.0: the API tracks latest stable Rust and will change.
Testing
The Postgres end-to-end suite skips itself unless OXIDER_POSTGRES_URL is set, so a plain cargo test still needs no server. CI runs a Postgres service so the suite is not merely skipped everywhere. Locally:
make pg-up # a throwaway PostgreSQL in Docker
make test-pg
make pg-downIt covers what only a real strict server can prove: temporals typed as the columns actually are, an instant surviving a session time-zone change, DISTINCT ON and a native aggregate FILTER on an engine that has them, named parameters, and a transaction rolling back with the caller's own error intact.
Known gaps
- The MySQL execution backend. With two
Backendimplementations proven and MySQL's lenient typing, it should be close to the SQLite shape. - PostgreSQL and MySQL codegen backends.
#[derive(Projection)], and a GroupBy transformer.- The renderer clones each
Valueinto the parameter list. - A tree thousands of subqueries deep can still overflow when dropped. Rendering it is refused either way.
Upgrading from v0.1.0
Nothing to change unless you depended on the exact text of a DateTime<Utc> parameter, which now carries +00:00 from a format specifier rather than a literal. The rendered string is the same.