--- title: "Trino" slug: "dev-database-integrations-trino" description: "Integrate VAST DataBase with Trino using the VAST connector for seamless SQL queries, transactions, and enhanced row and column security." updated: 2026-10-30T18:18:46Z published: 2026-10-30T18:18:46Z canonical: "docs.vastdata.com/dev-database-integrations-trino" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.vastdata.com/llms.txt > Use this file to discover all available pages before exploring further. # Trino *Applies to VAST Cluster 5.5.* With the VAST connector for Trino, VAST DataBase appears in Trino as a catalog. You use ordinary Trino SQL to create tables, insert rows, query them and run transactions. This page covers what you need to know from the Trino side: how names map, which catalog properties matter, what VAST DataBase does for your queries, and how row and column security changes what you see. ## Before you start Whoever runs your Trino cluster needs to install the connector and add a VAST catalog. VAST ships a Trino server with the connector built in as a Docker image, `vastdataorg/trino-vast` on Docker Hub, with an image for each cluster version. **Admin task: send to your platform team.** The install and configuration steps are in the KB: [Installing and configuring the VAST connector for Trino](/docs-5-5/docs/installing-and-configuring-the-vast-connector-for-trino). For the database, the endpoint, the access keys and the identity policy, see [setup prerequisites](/develop/docs/dev-database-operations-setup-prerequisites). What it needs, in short: - A running Trino cluster with a low-latency, high-bandwidth network connection to the VAST cluster. - A catalog file, `vast.properties`, with the endpoint and an access key pair (see [catalog properties](/develop/docs/dev-database-integrations-trino#catalog-properties)). - Three JVM options in `jvm.config`: ``` --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-exports=java.base/sun.nio.ch=ALL-UNNAMED ``` ## Version pairing The connector is numbered to match Trino. On VAST Cluster 5.5, use Trino 478 with connector 478. The full table, including older clusters, is in [version compatibility](/develop/docs/dev-database-reference-versions#trino). ## Catalog properties This catalog file works with Trino 478. Trino names a catalog after its file, so `vast.properties` gives a catalog called `vast`. ``` connector.name=vast endpoint={VAST_ENDPOINT} region=us-east-1 access_key_id={VAST_ACCESS_KEY_ID} secret_access_key={VAST_SECRET_ACCESS_KEY} data_endpoints={VAST_DATA_ENDPOINTS} num_of_splits=64 num_of_subsplits=10 vast.http-client.request-timeout=100h vast.http-client.idle-timeout=290s vast.http-client.max-connections-per-server=50 compression=zstd ``` With this file, the catalog runs DDL, `INSERT`, `UPDATE`, `DELETE` and `SELECT` against VAST Cluster 5.5. Two properties you may see in other examples don't work with Trino 478: - **No `vast.http-client.max-connections`.** Trino 478 refuses to start if a catalog file sets it: `Defunct property 'vast.http-client.max-connections' (class [class HttpClientConfig]) cannot be configured.` - **`compression`, not `vast.compression`.** As a catalog property, `vast.compression` is rejected (`Configuration property 'vast.compression' was not used`). `vast.compression` is the name of the matching *session* property for a catalog called `vast`. | Property | Example value | What it is | | --- | --- | --- | | `connector.name` | `vast` | Selects the VAST connector. | | `endpoint` | `{VAST_ENDPOINT}` | The VAST DataBase endpoint. | | `data_endpoints` | `{VAST_DATA_ENDPOINTS}` | Not described on the Trino page. | | `region` | `us-east-1` | Not described. | | `access_key_id`, `secret_access_key` | Your key pair | The S3 access key pair the connector uses. | | `num_of_splits` | 64 (standalone example), 512 (managed app) | A preliminary tuning parameter. If the catalog file doesn't set it, connector 478 uses 1 split, so set it. | | `num_of_subsplits` | 10 (standalone example), 4 (managed app) | A preliminary tuning parameter. | | `vast.http-client.request-timeout` | `100h` | Request timeout. | | `vast.http-client.idle-timeout` | `290s` | Idle timeout. | | `vast.http-client.max-connections-per-server` | 50 | | | `compression` | `zstd` | Optional. Compresses data on the wire, using Zstandard. In a catalog file it's `compression`; Trino 478 rejects `vast.compression` there. | The catalog holds one key pair. Unless end-user impersonation is set up (see [row and column security](/develop/docs/dev-database-integrations-trino#row-and-column-security)), the cluster checks permissions against that key's user, not against the person running the query. Ask for a key whose identity policy allows only what your Trino users need. The actions are listed in [setup prerequisites](/develop/docs/dev-database-operations-setup-prerequisites#permissions). ### Session properties Several catalog properties are also session properties, so you can change them for one session without editing the catalog file. With connector 478 these include `num_of_splits`, `num_of_subsplits`, `data_endpoints`, `compression` and the pushdown switches in [what VAST DataBase does for your query](/develop/docs/dev-database-integrations-trino#what-vast-database-does-for-your-query). For a catalog called `vast`, their names start with `vast.`: ``` SET SESSION vast.num_of_splits = 128; SET SESSION vast.num_of_subsplits = 4; SHOW SESSION LIKE 'vast.num_of_s%'; ``` `SHOW SESSION` then lists `vast.num_of_splits` with value `128` and default `64`, and `vast.num_of_subsplits` with value `4` and default `10`; the default is the catalog file's value. Run `SHOW SESSION LIKE 'vast.%'` to see every property your connector version has, with a description of each. ## Names: databases, schemas and tables VAST DataBase has databases, schemas and tables. Trino has catalogs, schemas and tables. The connector joins the database and schema into one Trino schema name, `<database>/<schema>`. Because of the `/`, quote it: The examples on this page use a database (bucket) called `vastdb`. Create a schema in it: ``` CREATE SCHEMA vast."vastdb/schema1"; ``` Then list what the catalog's key can see: ``` SHOW SCHEMAS FROM vast; SHOW TABLES FROM vast."vastdb/schema1"; ``` ``` Schema -------------------- information_schema system_schema vastdb/schema1 (3 rows) Table ------- (0 rows) ``` `SHOW SCHEMAS FROM vast` lists every database and schema the key can see, plus Trino's own `information_schema` and the connector's `system_schema`. In an interactive session, `USE vast."vastdb/schema1";` saves typing the prefix. ## Creating tables and writing data DDL and DML work as in any Trino catalog. This is the verification sequence (see [Installing and configuring the VAST connector for Trino](/docs-5-5/docs/installing-and-configuring-the-vast-connector-for-trino)): ``` CREATE TABLE vast."vastdb/schema1".cats ( weight BIGINT, name VARCHAR, attitude REAL, date DATE, time TIMESTAMP ); DESCRIBE vast."vastdb/schema1".cats; ``` ``` Column | Type | Extra | Comment ----------+--------------+-------+--------- weight | bigint | | name | varchar | | attitude | real | | date | date | | time | timestamp(3) | | (5 rows) ``` `TIMESTAMP` with no precision became `timestamp(3)`, Trino's default. For how Trino types map to VAST DataBase types, see [data types](/develop/docs/dev-database-reference-data-types). Transactions work with `START TRANSACTION` and `COMMIT`: ``` START TRANSACTION; INSERT INTO vast."vastdb/schema1".cats VALUES (12, 'happy', 18.7, date('2022-12-02'), now()); INSERT INTO vast."vastdb/schema1".cats VALUES (8, 'joy', 19.2, date('2022-12-02'), now()); COMMIT; SELECT weight, name, attitude, date FROM vast."vastdb/schema1".cats ORDER BY weight; ``` ``` weight | name | attitude | date --------+-------+----------+------------ 8 | joy | 19.2 | 2022-12-02 12 | happy | 18.7 | 2022-12-02 (2 rows) ``` ### Partitioned tables Set partitioning when you create the table, with the `partitioning` table property. You can't add or change it later. ``` CREATE TABLE vast."vastdb/schema1".events ( event_id int, event_time timestamp(6), event_type varchar ) WITH ( partitioning = ARRAY['day(event_time)', 'event_type'] ); SHOW CREATE TABLE vast."vastdb/schema1".events; ``` ``` Create Table --------------------------------------------------------- CREATE TABLE vast."vastdb/schema1".events ( event_id integer, event_time timestamp(6), event_type varchar ) WITH ( partitioning = ARRAY['Day(event_time)','event_type'] ) (1 row) ``` This creates a partition for each combination of day and event type. The transforms (`identity`, `bucket`, `truncate`, `year`, `month`, `day`, `hour`) are listed in [Database partitioning](/docs-5-5/docs/database-partitioning). What partitioning can be combined with is in [limits](/develop/docs/dev-database-reference-limits). Each partition shows up in the table's `$partitions` table. A transformed column is named with the transform as a suffix, so `day(event_time)` becomes `event_time_day` (and `bucket(col2, 1024)` would be `col2_bucket`): ``` INSERT INTO vast."vastdb/schema1".events VALUES (1, TIMESTAMP '2026-09-16 10:00:00', 'click'), (2, TIMESTAMP '2026-09-16 11:00:00', 'view'), (3, TIMESTAMP '2026-09-17 10:00:00', 'click'); SELECT event_time_day, event_type FROM vast."vastdb/schema1"."events$partitions" ORDER BY event_time_day, event_type; ``` ``` event_time_day | event_type ----------------+------------ 2026-09-16 | click 2026-09-16 | view 2026-09-17 | click (3 rows) ``` To delete whole partitions, delete from `$partitions`, with the `vast.allow_non_acid` flag appended to the name: ``` DELETE FROM vast."vastdb/schema1"."events$partitions vast.allow_non_acid" WHERE event_time_day = DATE '2026-09-16' AND event_type = 'click'; SELECT event_id, event_type FROM vast."vastdb/schema1".events ORDER BY event_id; ``` ``` event_id | event_type ----------+------------ 2 | view 3 | click (2 rows) ``` As the flag says, this isn't ACID. Changing partitions while other writes go to the same table can leave the data in an indeterminate state. Don't run it while anything else writes to the table. ### Sorted tables You can make an existing table sorted with the `sorted_by` table property: ``` ALTER TABLE vast."vastdb/schema1".cats SET PROPERTIES sorted_by = ARRAY['weight', 'name']; SHOW CREATE TABLE vast."vastdb/schema1".cats; ``` ``` Create Table ------------------------------------------- CREATE TABLE vast."vastdb/schema1".cats ( weight bigint, name varchar, attitude real, date date, time timestamp(3) ) WITH ( sorted_by = ARRAY['weight','name'] ) (1 row) ``` Once a table is sorted, you can't turn sorting off, change the sort columns or update their values. The other rules are in [limits](/develop/docs/dev-database-reference-limits). ### Views You can create views from Trino. They're stored in the database. The examples are in the [KB](/docs-5-5/docs/installing-and-configuring-the-vast-connector-for-trino#creating-database-views). In 5.5: - View properties aren't supported. - Nested data types aren't supported in views created from Trino. - The `SECURITY` clause of `CREATE VIEW` isn't supported. - Queries in a view must use full table names. - If the schema of the query changes when a view is redefined, its user-defined column names and comments are lost. - Trino has no command that lists only views. Use a naming convention instead, such as a `_view` suffix, and `SHOW TABLES ... LIKE '%_view%'`. ## What VAST DataBase does for your query When Trino scans a VAST table, VAST DataBase does part of the work: it returns only the columns the query needs, returns the count for a whole-table `COUNT(*)`, and evaluates the filters the connector can hand it. With Trino 478: | Pushed down to VAST DataBase | Filtered by Trino | | --- | --- | | Comparisons, `<>`, ranges, `BETWEEN`, `IN`, `IS NULL`, on integers, decimals, doubles, booleans, strings, dates and timestamps | `LIKE` with any other pattern: `'app%'`, `'%ple'`, or a pattern with `_` or an escape inside, such as `'%a_a%'` | | `OR` on one column; `AND` across columns | `OR` across columns, unless you turn on `complex_predicate_pushdown` (below) | | `LIKE '%substring%'`, a substring with no other wildcards | A substring `LIKE` on a column that also has another filter, such as `s LIKE '%nan%' AND s = 'banana'` | | | Comparing two columns, functions (`upper()`, `substr()`) and arithmetic (`a + 1`) | The connector's session properties change what's pushed down. Their defaults in Trino 478: | Session property | Default | Effect | | --- | --- | --- | | `vast.match_substring_pushdown` | `true` | Pushes down `LIKE '%substring%'`. | | `vast.complex_predicate_pushdown` | `false` | Pushes down an `OR` across columns, such as `a = 1 OR b = 20`. An `OR` of `AND`s, such as `(a = 1 AND b = 10) OR (a = 5 AND b = 20)`, still isn't pushed down. | | `vast.expression_projection_pushdown` | `false` | Pushes down computed columns (column expression projection). | Set one for a session with `SET SESSION vast.complex_predicate_pushdown = true;`. Run `SHOW SESSION LIKE 'vast.%'` to see them all. Trino does everything else on the rows that come back. In this query, for example, VAST DataBase evaluates both `WHERE` conditions and Trino computes the average: ``` SELECT avg(weight) AS avg_weight FROM vast."vastdb/schema1".cats WHERE weight > 5 AND attitude < 20; ``` ``` avg_weight ------------ 10.0 (1 row) ``` The full list of predicates is in [pushdowns](/develop/docs/dev-database-reference-pushdowns). ### EXPLAIN `EXPLAIN` works on VAST tables. It's the last check that the connector is set up: ``` EXPLAIN SELECT * FROM vast."vastdb/schema1".cats WHERE weight > 10 AND attitude < 10; ``` In the plan, the `TableScan` line lists each column's predicate as VAST DataBase will evaluate it, and a `Filter` or `ScanFilterProject` step above it is what Trino evaluates. For this query it holds `SortedRangeSet[type=bigint, ranges=1, {(10,<max>)}]` for `weight` and `SortedRangeSet[type=real, ranges=1, {(<min>,10.0)}]` for `attitude` *(Trino 478, VAST Cluster 5.5)*. A condition that isn't listed there is evaluated by Trino. The plan also carries the table's internal handle, which changes from run to run. The same holds for plain, sorted and partitioned tables: the pushed-down predicate is in the `TableScan` in each case. On a sorted table the scan also lists the sort columns (`sorted_by@[Optional[[cust]]]` for a table sorted on `cust`). A function such as `upper(region) = 'EU'` stays in Trino, as a `filterPredicate` in a `ScanFilterProject` step, while the plain conditions next to it are still pushed down. The plan doesn't show which partitions are skipped. More on pushdowns, including dynamic filtering for joins, is in [pushdowns](/develop/docs/dev-database-reference-pushdowns#trino). ### Partition pruning On a partitioned table, the query engine skips partitions that can't match the query. It can also line up its splits with partition boundaries, so that a group-by, or a join between two tables partitioned the same way on the join key, needs no shuffle ([Database partitioning](/docs-5-5/docs/database-partitioning)). Filter on the partition columns to benefit. ### Not available through Trino The VAST connector for Trino doesn't support vector index-based search. Vector search runs through the VAST Query Engine; see [Vector search](/docs-5-5/docs/vector-search). ## Row and column security Your platform team can add row and column security rules to identity policies. See [Row and column security](/docs-5-5/docs/row-and-column-security); [security](/develop/docs/dev-database-operations-security) covers how they affect your queries. What you see in Trino: - **Column allow and deny.** Denied columns aren't returned. With `ColumnAllow`, only the listed columns are returned. This applies to queries, inserts and renames. It works on top-level columns only, not on fields inside nested columns. - **Column masking.** The column is returned, but its values are replaced by a SQL expression from the policy, for example `regexp_replace(my_col_email, '.*', '***')`. The query doesn't fail. - **Row filters.** Rows that don't match the policy's filter are left out, as if the policy added a `WHERE` clause. - **Path-based row filters.** If a table has the reserved `vastdb_s3_path_auth` column, a row is returned only if the user may read every S3 path listed in it. VAST DataBase returns the filters and masks, and the query engine applies them. Each filter and mask names the engines it applies to, for example `"QueryEngine": "Trino"`. If a policy defines row filters or column masks for a user on a table, that user can query the table only through one of the engines named in the policy. If a query names a denied column, it fails as if the column didn't exist: `Column '<column>' cannot be resolved`. > **Warning:** a catalog without the security flags below doesn't apply row filters. A catalog that uses an end user's *own* key, with no flags set, removes that user's denied column but returns every row, ignoring the user's row filter. If your rules include row filters, use a catalog with the flags set. A catalog with a service key and no flags returns whatever that key's user may see, to every Trino user. ### What the catalog needs For the rules to apply to the person running the query, the connector has to act on their behalf (end-user impersonation). Two things are needed. **The security flags in the catalog file.** All three, with underscores: ``` enable_access_control=true enable_row_column_security=true enable_end_user_impersonation=true ``` Connector 478 rejects the names with hyphens, for example: `Configuration property 'enable-access-control' was not used. Did you mean to use 'enable_access_control'?` **Two actions for the catalog key's user.** The identity policy of the user who owns the key in the catalog file (the service user) must allow `s3:EndUserImpersonation` and `s3:TabularGetRowColumnSecurity`. `s3:Tabular*` covers the second but not the first. Without them, every query on the catalog fails with `403 Forbidden - ACCESS DENIED`, and the Trino server log has the cluster's reason: - Without `s3:EndUserImpersonation`, the query fails with `failed to execute request LIST_SCHEMA, path /vastdb not allowed`; the log says `action=EndUserImpersonation is not allowed (end_user=<trino-user>)`. - Without `s3:TabularGetRowColumnSecurity`, it fails with `failed to execute request ROW_COLUMN_SECURITY, path /vastdb/schema1/<table> not allowed`; the log says `action=TabularGetRowColumnSecurity is not allowed (end_user=<trino-user>)`. - `s3:GetRowColumnSecurity` doesn't help: the error is the same as without `s3:TabularGetRowColumnSecurity`. If you set `enable_access_control` and `enable_row_column_security` without impersonation, the key's own user needs `s3:TabularGetRowColumnSecurity`; otherwise every query fails with the `ROW_COLUMN_SECURITY` error above. **Admin task: send to your platform team.** See [Enabling row and column security configurations](/docs-5-5/docs/row-and-column-security#enabling-row-and-column-security-configurations). ### Which user the rules apply to The connector sends the Trino session user's name to the cluster as the end user. That name must be the login name of a VAST user; no mapping setting is needed. The cluster then applies that user's identity policy. If no VAST user has that name, the query fails with `403 Forbidden - ACCESS DENIED: failed to execute request LIST_SCHEMA, path /vastdb not allowed`, and the server log says `login_name=<trino-user> was not found`. If your Trino cluster has authentication, the session user is the authenticated user. With impersonation working: - A user with a row filter gets only the matching rows, and a denied column is gone: naming it gives `Column '<column>' cannot be resolved`. - `EXPLAIN` shows the row filter as a predicate in the `TableScan`, like any pushed-down filter, and leaves the denied column out. - Writes are checked as the end user too. An `INSERT` of a row that doesn't match the user's row filter fails with `Access Denied: Cannot insert row that does not match a row filter`, and an insert the user's policy doesn't allow fails with a 403 `Permission check failed`. - The service user itself, as a Trino user, sees what its own policy allows. ## Troubleshooting **A statement hangs instead of failing.** If the catalog's `endpoint` is wrong or unreachable, the connector retries each request rather than failing, so statements appear to hang. With the default retry settings, a statement against an endpoint that refused connections was still retrying after 11 minutes; the server log shows `retrying due to I/O error` every second. Check `endpoint` first when a new catalog's queries never return. **One entry in `data_endpoints` is down.** The query still completes with the right result. Requests to the dead entry are refused and retried, so the query only takes longer; the server log has `Server refused connection` lines naming that endpoint. Remove the entry, or ask your platform team which virtual IPs are current. ## Trino as a managed application on the cluster Trino can also run on the cluster's CNodes as a managed application. Connect to it with the Trino CLI on the coordinator's virtual IP, using the `vast` catalog: ``` ./trino --server :8080 --catalog vast --schema --user ``` Everything on this page applies to it too. Also: - The application image is Trino 475. Use a Trino CLI of the same version. - A cluster upgrade while the app runs can make queries fail. The app is fully working again once the upgrade completes. - The app keeps running queries through a CNode failure, as long as one coordinator CNode and one worker CNode stay up. **Admin task: send to your platform team.** Setting up the app is a DataEngine task: [Trino managed CNode applications](/docs-5-5/docs/trino-managed-cnode-applications) and [Managed applications on clusters](/docs-5-5/docs/managed-applications-on-clusters). ## Clean up ``` DROP TABLE vast."vastdb/schema1".cats; DROP TABLE vast."vastdb/schema1".events; DROP SCHEMA vast."vastdb/schema1"; ``` ## See also - [Spark](/develop/docs/dev-database-integrations-spark) - [Pushdowns](/develop/docs/dev-database-reference-pushdowns) - [Data types](/develop/docs/dev-database-reference-data-types) - [Version compatibility](/develop/docs/dev-database-reference-versions#trino) - [Security](/develop/docs/dev-database-operations-security) - [Performance](/develop/docs/dev-database-operations-performance)