Trino
| Status | verified |
|---|---|
| Reads | yes |
| Writes | yes (format version 2 tested) |
| Iceberg v3 | reads |
| Geometry, geography | geometry read; spherical distance for points only |
| Last verified | 2026-10-03 (Trino 483) |
Trino reads and writes Iceberg tables in a LakehouseBox catalog through its own Iceberg connector, pointed at our REST catalog. Trino asks the catalog for each table and gets short-lived storage credentials for that table with the answer, so the properties file holds only the catalog credential. Each catalog you connect is one Trino catalog.
Before you start
- A running Trino (one node is enough; the runs below used the
trinodb/trinocontainer image, version 483). For Iceberg v3geometryandgeographycolumns you need Trino 482 or newer, the first release that reads and writes them (Trino's release notes, 2026-06-25). - A catalog in LakehouseBox and
lhboxlogged in (lhbox login), or someone who can send you the recipe.
Connect
lhbox connect --catalog <catalog> --engine trino --show-secrets
prints a catalog properties file, with your catalog's storage location and credential filled in, and the name to save it under (etc/catalog/<catalog_name>.properties). Without --show-secrets the secret is printed as ********. It looks like this:
# etc/catalog/<catalog_name>.properties
connector.name=iceberg
iceberg.catalog.type=rest
iceberg.rest-catalog.uri=https://catalog.lakehousebox.com
iceberg.rest-catalog.warehouse=s3://<handle>--<catalog>/
iceberg.rest-catalog.security=OAUTH2
iceberg.rest-catalog.oauth2.credential=<client_id>:<client_secret>
iceberg.rest-catalog.oauth2.server-uri=https://catalog.lakehousebox.com/v1/oauth/tokens
iceberg.rest-catalog.vended-credentials-enabled=true
fs.native-s3.enabled=true
s3.endpoint=https://s3.lakehousebox.com
s3.region=us-east-1
s3.path-style-access=true
Save it, restart Trino, and the catalog is addressed as <catalog_name>.<namespace>.<table>.
- OAuth2 client credentials (
iceberg.rest-catalog.oauth2.credential,…oauth2.server-uri): Trino fetches its own catalog token with the catalog's key pair. - Vended credentials (
iceberg.rest-catalog.vended-credentials-enabled=true): the storage keys come from the catalog with each table, for one hour, scoped to that table. s3.region=us-east-1is the signing region the storage accepts; keep it, and keeps3.path-style-access=true.
Reading
Verified 2026-09-28 with Trino 483 and the properties above unchanged, on a format-version 2 table written by PyIceberg 0.12: SHOW SCHEMAS, SHOW TABLES, count(*) and a filtered SELECT all returned the expected rows.
Iceberg format version 3 tables read too: on 2026-10-03 Trino 483 counted every row of six v3 tables of 7.1 to 81.5 million rows each (Overture roads, buildings and places), written by lhbox table import and by Spark 4.1 with Iceberg 1.12, and read their geometry values (below).
Writing
Verified 2026-09-28 with Trino 483 and the same properties: INSERT into the PyIceberg-written table, and CREATE TABLE … AS SELECT creating a new table in the catalog; both read back as expected (6 rows after the insert, 3 in the new table).
Writes to a format-version 3 table, and UPDATE, DELETE and MERGE, have not been run against LakehouseBox yet.
The read-only recipe
lhbox connect --catalog <catalog> --engine trino --readonly --show-secrets
prints the same file with the catalog's read-only key pair: the one to give a colleague who should only read. Name the file differently (for example <catalog_name>_ro.properties) if you keep both. Verified 2026-09-28: reads work; writes are refused, INSERT by the storage (Trino reports Error committing write to Parquet file, caused by AccessDenied on the data file) and CREATE TABLE by the catalog (Failed to create transaction, caused by not authorized to create table in this namespace). The table was unchanged afterwards.
Geometry and geography
Measured on 2026-10-03 with Trino 483 on the public Overture tables (research run of that date), against answers computed separately from the source files:
- Types. An Iceberg
geometrycolumn is a TrinoGeometry, ageographycolumn aSphericalGeography. - Box questions on geometry are right, but read whole tables.
ST_Intersects(geometry, ST_Envelope(…))returned the exact counts (14,881 road segments in central Valencia, 3,357 buildings around Puerta del Sol, 25,355 places in central Madrid), reading 1.08 GB in 18 s, 2.03 GB in 42 s and 913 MB in 29 s from one node. Trino does not use the geometry bounds in the table's metadata to skip files, where DuckDB 1.5.6 answers the same questions reading 2.5–9.3 MB. - Spherical distance works for points only.
ST_Distance(geography, to_spherical_geography(ST_Point(…))) <= 1000on places counted 11,822, the right answer. On lines and polygons Trino refuses:When applied to SphericalGeography inputs, ST_Distance only supports POINT. Input type is: LINE_STRING(andPOLYGON). Converting withto_geometry(geography)reads the values as planar geometry.
These runs used a static storage key in the properties file (vended-credentials-enabled=false with s3.aws-access-key / s3.aws-secret-key) rather than vended credentials; the printed recipe, with vended credentials, is the one verified on 2026-09-28 above.
Known limitations
As measured with Trino 483:
- Tables Snowflake writes cannot be read yet. Snowflake records their file paths as
s3compat://…, which the Iceberg spec allows but Trino does not recognise: it fails withError processing metadata(2026-10-03). Spark 4.1 with Iceberg 1.12 reads the same tables. - No file skipping on spatial filters, so a box question scans the whole table (above). Trino does not yet write geometry bounds either (Trino issue #30077, open).
- Spherical distance on lines and polygons is refused (above). Not reported upstream yet.