You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build a read-only Rust-based ODBC driver for Trino, targeting PowerBI on Windows.
Authentication scope: Basic Auth only for all three milestones.
The driver will be built using the trino-rust-client rather than implementing a Trino Rust REST client from scratch.
Reusability note
The FFI scaffolding must be designed for reuse so a second ODBC driver can later be built without duplicating the boilerplate.
This will need some brainstorming. During my implementation of our odbc-rs-sqlite experiment I learned that any Trait or whatever based systems will not work as the FFI methods have to have an exact name and signature and their handling code can also not be general but needs to be specific. I believe the only way we can do this is to have a macro-based crate. One idea I had was a kind of "Backend" trait. A macro generates all the required extern "system" entry points and then forwards to a type implementing the trait.
This is not necessarily an immediate goal of this project but it'd be nice if we could already design it in a similar way (i.e. already decouple the database logic from the ODBC wrapper stuff by e.g. already using a trait).
Tip
We have an existing experiment (odbc-rs-sqlite) that serve as reference material, but it probably makes sense to start from scratch.
Important
We may eventually need to contribute a step-by-step polling API (advance()) to trino-rust-client to avoid buffering entire result sets in memory. This is not needed for Import mode but will matter for large datasets and DirectQuery. Out of scope for now.
Out of Scope
Write operations (architecture should support it eventually, but no implementation here)
OIDC / OAuth -> Basic Auth only, but design for the possibility of having more than one auth system
Spooling protocol
DSN setup GUI or Windows installer
A second ODBC driver using the reusable framework
Publishing the reusable crate separately
advance() / streaming API contribution to trino-rust-client
Milestone 1: Foundation DLL — "Does it load?"
Expected effort: 2–3 weeks. If it takes longer, stop and flag.
A Windows DLL that can be registered in the ODBC Driver Manager and entered into PowerBI Gateway. It does not need to connect to anything. Every function call may return SQL_ERROR. The goal is to validate the build and delivery pipeline end-to-end.
Port reusable scaffolding from odbc-rs-sqlite: HandleWrapper, FFI utilities, error/SQLSTATE types
Backend trait abstraction separating ODBC protocol logic from database-specific logic, including the macro that generates all ODBC entry points
All required ODBC entry points exported as stubs (return SQL_ERROR)
extern "system" calling convention throughout (not extern "C")
Cross-compile to Windows DLL (x86_64-pc-windows-gnu or MSVC via xwin) -> verify it loads
Configuration via env vars or .ini file - this needs research: I have no idea how to configure ODBC drivers in Windows
Decision point: Customer confirms the DLL registers and appears in PowerBI Gateway without errors. Don't start Milestone 2 until this is confirmed.
Milestone 2: Import Mode — "PowerBI can pull a table"
Expected effort: 4–5 weeks. If it takes longer, stop and flag.
PowerBI Import mode can connect to Trino, browse tables, and import data.
Integrate trino-rust-client with tokio (one Runtime per connection, block_on() at FFI boundaries)
SQLDriverConnect with Basic Auth + TLS
SQLGetInfo (~50 info type values -> start from Trino's C++ driver as reference but will need to test against PowerBI)
SQLGetFunctions report only what is actually implemented
SQLExecDirect (use get_all())
SQLFetch + SQLGetData with type conversion for: varchar, char, bigint, integer, smallint, tinyint, double, real, boolean, decimal, uuid, date, time, timestamp, timestamp with time zone
Panic safety: every FFI entry point wrapped in std::panic::catch_unwind
Memory safety audit: no use-after-free when connection freed while statements exist
Decision point: Customer successfully imports at least one Trino table into PowerBI. Sign off before starting Milestone 3.
Milestone 3: DirectQuery Mode — "Live queries from PowerBI"
Expected effort: 4–7 weeks. If it takes longer, stop and flag.
PowerBI DirectQuery works. This requires both driver changes and a Power Query custom connector (.mez file). The .mez is a separate deliverable written in M language. Nobody on the team has done this before. Will require research. Flag if this becomes a blocker
Power Query custom connector (.mez): SqlCapabilities overrides, AstVisitor to emit LIMIT/OFFSET instead of TOP N, double-quote identifiers instead of square brackets
SQLGetInfo capability tuning for DirectQuery: SQL_SQL_CONFORMANCE, predicate support, aggregate functions, subquery support
SQLPrepare + SQLExecute
SQLFetchScroll (forward-only)
SQLCancel via Trino's partialCancelUri
Streaming result delivery (no full buffering)
Integration testing: filters, grouping, aggregations, joins — verify all fold to SQL
Decision point: Customer confirms an interactive PowerBI dashboard with filters and aggregations works against live Trino data, with queries folding to SQL.
Acceptance Criteria
These points are awaiting user feedback:
Milestone 1: DLL registers in ODBC Driver Manager and appears in PowerBI Gateway on customer's Windows machine
Milestone 2: Customer imports a Trino table into PowerBI Import mode successfully
Milestone 3: Customer builds a live dashboard using DirectQuery with filters and aggregations folding to SQL
Trino ODBC Driver (Rust)
Description
Build a read-only Rust-based ODBC driver for Trino, targeting PowerBI on Windows.
Authentication scope: Basic Auth only for all three milestones.
The driver will be built using the
trino-rust-clientrather than implementing a Trino Rust REST client from scratch.Reusability note
The FFI scaffolding must be designed for reuse so a second ODBC driver can later be built without duplicating the boilerplate.
This will need some brainstorming. During my implementation of our
odbc-rs-sqliteexperiment I learned that any Trait or whatever based systems will not work as the FFI methods have to have an exact name and signature and their handling code can also not be general but needs to be specific. I believe the only way we can do this is to have a macro-based crate. One idea I had was a kind of "Backend" trait. A macro generates all the requiredextern "system"entry points and then forwards to a type implementing the trait.This is not necessarily an immediate goal of this project but it'd be nice if we could already design it in a similar way (i.e. already decouple the database logic from the ODBC wrapper stuff by e.g. already using a trait).
Tip
We have an existing experiment (
odbc-rs-sqlite) that serve as reference material, but it probably makes sense to start from scratch.Important
We may eventually need to contribute a step-by-step polling API (advance()) to trino-rust-client to avoid buffering entire result sets in memory. This is not needed for Import mode but will matter for large datasets and DirectQuery. Out of scope for now.
Out of Scope
Milestone 1: Foundation DLL — "Does it load?"
Expected effort: 2–3 weeks. If it takes longer, stop and flag.
A Windows DLL that can be registered in the ODBC Driver Manager and entered into PowerBI Gateway. It does not need to connect to anything. Every function call may return
SQL_ERROR. The goal is to validate the build and delivery pipeline end-to-end.odbc-corecrate (generic FFI infrastructure) +odbc-driver-trinocrate (cdylib)odbc-rs-sqlite:HandleWrapper, FFI utilities, error/SQLSTATE typesBackendtrait abstraction separating ODBC protocol logic from database-specific logic, including the macro that generates all ODBC entry pointsSQL_ERROR)extern "system"calling convention throughout (notextern "C")x86_64-pc-windows-gnuor MSVC via xwin) -> verify it loads.inifile - this needs research: I have no idea how to configure ODBC drivers in WindowsMilestone 2: Import Mode — "PowerBI can pull a table"
Expected effort: 4–5 weeks. If it takes longer, stop and flag.
PowerBI Import mode can connect to Trino, browse tables, and import data.
trino-rust-clientwith tokio (oneRuntimeper connection,block_on()at FFI boundaries)SQLDriverConnectwith Basic Auth + TLSSQLGetInfo(~50 info type values -> start from Trino's C++ driver as reference but will need to test against PowerBI)SQLGetFunctionsreport only what is actually implementedSQLExecDirect(useget_all())SQLFetch+SQLGetDatawith type conversion for: varchar, char, bigint, integer, smallint, tinyint, double, real, boolean, decimal, uuid, date, time, timestamp, timestamp with time zoneSQLNumResultCols,SQLDescribeCol,SQLColAttributeSQLTables+SQLColumnsviasystem.jdbc.*queriesSQLGetTypeInfo,SQLStatisticsSQLGetDiagRec,SQLGetDiagFieldSQLMoreResults,SQLRowCount,SQLCloseCursorstd::panic::catch_unwindMilestone 3: DirectQuery Mode — "Live queries from PowerBI"
Expected effort: 4–7 weeks. If it takes longer, stop and flag.
PowerBI DirectQuery works. This requires both driver changes and a Power Query custom connector (.mez file). The .mez is a separate deliverable written in M language. Nobody on the team has done this before. Will require research. Flag if this becomes a blocker
SqlCapabilitiesoverrides,AstVisitorto emitLIMIT/OFFSETinstead ofTOP N, double-quote identifiers instead of square bracketsSQLGetInfocapability tuning for DirectQuery:SQL_SQL_CONFORMANCE, predicate support, aggregate functions, subquery supportSQLPrepare+SQLExecuteSQLFetchScroll(forward-only)SQLCancelvia Trino'spartialCancelUriAcceptance Criteria
These points are awaiting user feedback: