Trino Compatibility
SQE includes a Trino-compatible HTTP endpoint that allows existing Trino clients (JDBC drivers, CLI tools, DBeaver) and Trino-speaking BI tools (Metabase, Superset) to connect without modification.
Enabling
The Trino HTTP endpoint is enabled by default on port 8080. Set port to 0 to disable:
[coordinator]
trino_http_port = 8080 # 0 to disable
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/v1/info | GET | Node info (version, uptime, coordinator status) |
/v1/info/state | GET | Plain text: ACTIVE or STARTING |
/v1/statement | POST | Submit a SQL query |
/v1/statement/queued/{id}/{slug}/{token} | GET | Poll a queued/running query until results are ready (finding 702) |
/v1/statement/{id}/{slug}/{token} | GET | Fetch paginated results (finding 702) |
/v1/statement/{id} | DELETE | Cancel a running query |
Authentication
The Trino endpoint supports two authentication methods:
Bearer Token
Pass an existing access token directly:
curl -H "Authorization: Bearer eyJhbG..." \
-H "X-Trino-User: alice" \
-d "SELECT 1" \
http://localhost:8080/v1/statement
Basic Auth
Username and password are exchanged for a token via the configured OIDC/OAuth2 backend:
curl -u alice:password \
-d "SELECT 1" \
http://localhost:8080/v1/statement
Client Headers
SQE respects standard Trino client headers:
| Header | Purpose |
|---|---|
X-Trino-User | Override username (used with Bearer auth) |
X-Trino-Catalog | Set default catalog for the session |
X-Trino-Schema | Set default schema for the session |
X-Trino-Source | Client identifier (logged for audit) |
Result Pagination
Query results are paginated. The initial response includes a nextUri field. Follow nextUri links to retrieve subsequent pages:
{
"id": "query-uuid",
"stats": { "state": "FINISHED" },
"columns": [{"name": "result", "type": "integer"}],
"data": [[1]],
"nextUri": "http://localhost:8080/v1/statement/query-uuid/1"
}
When nextUri is absent, all results have been consumed.
Poll Token Security (finding 702)
Every nextUri in poll responses carries a session-binding token ({slug}/{token} in the URL) that proves the poll is from the same client that submitted the query. Clients must:
- Follow
nextUriverbatim (SQE clients do this already via the JDBC driver and CLI). - Pass credentials only on the initial
POST /v1/statement; subsequent polls on{slug}/{token}do not require authentication if the token is valid.
The rate limiter runs on every route (including polls), protecting against credential-guessing attacks. A token is 32 random bytes (base64url, non-predictable). Ownership is checked by session ID and subject (sub claim), not by display username, so a second authentication provider in the chain cannot hijack another user’s session.
The two-segment GET /v1/statement/{id} form (without slug/token) is no longer accepted; clients must use the three-segment form with the poll token from the previous response’s nextUri.
Async Submission
Submission is async, matching Trino’s own protocol. POST /v1/statement spawns the query on a background task with a bounded initial wait. If the query does not finish in that window, the first response carries state: QUEUED, no data, and a nextUri pointing at /v1/statement/queued/{id}/{token}:
{
"id": "query-uuid",
"stats": { "state": "QUEUED" },
"nextUri": "http://localhost:8080/v1/statement/queued/query-uuid/0"
}
The client follows the queued links (state stays QUEUED or RUNNING) until the query finishes, at which point nextUri redirects to the results route at token 0 and the response starts carrying columns and data. Clients that only ever poll nextUri need no special handling: the queued and results routes chain transparently.
Using with the CLI
sqe-cli --protocol http --host localhost --port 8080 --user alice
Connecting External Tools
DBeaver
- Create a new Trino connection
- Host:
localhost, Port:8080 - Authentication: Username/Password
- Driver properties: no special settings needed
JDBC (Java)
String url = "jdbc:trino://localhost:8080";
Properties props = new Properties();
props.setProperty("user", "alice");
props.setProperty("password", "secret");
Connection conn = DriverManager.getConnection(url, props);
Metabase and Superset
BI tools that speak Trino connect through the same endpoint. Metabase uses the Trino JDBC driver, Superset uses the Trino SQLAlchemy dialect (trino://user@host:8080/catalog). Both drive a metadata handshake on connect (prepare a statement, enumerate catalogs and schemas, list tables, describe columns) before running a chart, and SQE now matches Trino’s exact response shape at each step:
PREPAREandDEALLOCATE PREPAREare handled as session-control via theX-Trino-Added-Prepare/X-Trino-Deallocated-Prepareheaders, so the JDBC connection test succeeds.SHOW TABLESreturns a singleTablecolumn,SHOW SCHEMASaSchemacolumn, andSHOW CATALOGSaCatalogcolumn, so schema sync reads the right values.SHOW CATALOGSand thesystem.jdbc.*/system.metadata.*tables enumerate every reachable catalog and skip the ones the caller is not authorized to list, andSHOW TABLES/SHOW SCHEMAShonor the session catalog (X-Trino-Catalog).DESCRIBEandSHOW COLUMNSresolve double-quoted identifiers ("catalog"."schema"."table"), so field discovery works.- Types map to their Trino equivalents:
timestamp(6)carries its precision in the type signature (so date bucketing over JDBC works), and computed unsigned-64 aggregates likecount(*)map tobigintrather thandecimal.
Metadata statements
SHOW SCHEMAS FROM <catalog> and SHOW TABLES FROM <catalog>.<schema> answer
for the catalog they name, not the session catalog. A trailing
LIKE '<pattern>' filters the names the way Trino does: % matches any run,
_ one character, and the match is case-sensitive (ILIKE is not). dbt-trino
checks whether a schema exists with exactly this form:
SHOW SCHEMAS FROM ws_cbs_energy LIKE 'cbs_silver';
SHOW TABLES FROM ws_cbs_energy.cbs_silver LIKE 'fact%';
ESCAPE is not accepted on SHOW statements, so _ in a pattern always
matches any single character.
A catalog that does not exist, or that the caller may not see, fails with
Trino’s error: Catalog 'x' does not exist (CATALOG_NOT_FOUND). The two
cases read the same, so the reply does not reveal which one applies. A
catalog the caller can reach but whose schemas it may not list returns an
empty result.
Limitations
- The Trino endpoint returns results as JSON (Trino wire format), not Arrow. For maximum performance, use Flight SQL.
START TRANSACTION(what JDBC sends aftersetAutoCommit(false)) answers withX-Trino-Started-Transaction-Id, and a successfulCOMMIT/ROLLBACKwithX-Trino-Clear-Transaction-Id. Unlike Trino’s Iceberg connector, DML inside the transaction runs on a private branch andCOMMITpublishes it (see Transactions). DDL still fails withAUTOCOMMIT_WRITE_CONFLICT(“Catalog only supports writes using autocommit”). The id belongs to the coordinator that issued it: another coordinator, or the same one after a restart, answersTRANSACTION_CONFLICT.SNAPSHOTisolation and savepoints are refused.- Type mapping covers common types; complex nested types may differ from native Trino behavior.
- Iceberg hidden columns (
$path,$file_modified_time,$partition) are not exposed on table scans. They need a per-row, per-source-file column that is resolvable by name but excluded fromSELECT *. DataFusion has no such metadata-column mechanism yet (tracked upstream at apache/datafusion#20135, not in any release), and adding the column to the scan schema would make everySELECT *return it. For file-level introspection use thetable_files('ns', 't')table function, which listsfile_path,record_count, andfile_size_in_bytesper data file. - Materialized views are not supported.
CREATE MATERIALIZED VIEWreturns a clear “not supported” error rather than creating a plain view.DROP MATERIALIZED VIEW IF EXISTSis treated as a no-op so client tooling that issues it on teardown can proceed.
Flight SQL vs Trino HTTP
| Aspect | Flight SQL (default) | Trino HTTP |
|---|---|---|
| Port | 50051 | 8080 |
| Wire format | Arrow IPC (binary, columnar) | JSON |
| Performance | High (zero-copy) | Lower (serialization overhead) |
| Client support | ADBC, JDBC (Flight SQL), dbt | Trino JDBC, DBeaver, Metabase, Superset |
| Pagination | Arrow Flight streaming | nextUri polling |
Use Flight SQL for performance-sensitive workloads. Use Trino HTTP for compatibility with existing tools.