1. Introduction

Redis SQL Trino is a Trino connector which allows access to RediSearch data from Trino.

This guide provides documentation and usage information across the following topics:

2. Installation

2.1. Trino

Trino installation instructions are available at https://trino.io/docs/current/installation.html.

2.2. RediSearch connector

Download latest release and unzip without any directory structure under:

<trino>/plugin/redisearch

Create a RediSearch connector configuration file and change/add properties as needed.

3. Configuration

To configure the RediSearch connector, create a catalog properties file and change/add properties as needed.

etc/catalog/redisearch.properties
connector.name=redisearch
redisearch.uri=redis://localhost:6379
Table 1. Connector properties
Property name Description Default

redisearch.default-schema-name

The schema that contains all tables defined without a qualifying schema name.

default

redisearch.case-insensitive-names

Match index names case insensitively.

false

redisearch.cursor-count

Number of rows read during each aggregation cursor fetch.

1000

redisearch.table-cache-refresh

Seconds an index’s schema is cached. Indexes and fields created outside Trino can take this long to appear.

60

Table 2. Redis connection properties
Property name Description Default

redisearch.uri

A Redis connection string. Redis URI syntax.

redisearch.username

Redis connection username.

redisearch.password

Redis connection password.

redisearch.cluster

Connect to a Redis Cluster.

false

redisearch.resp2

Force Redis protocol version to RESP2.

false

The RediSearch connector provides additional security options to support Redis servers with TLS mode.

Table 3. TLS properties
Property name Description Default

redisearch.insecure

Allow insecure connections (e.g. invalid certificates) when using SSL.

false

redisearch.cacert-path

X.509 CA certificate file to verify with.

redisearch.key-path

PKCS#8 private key file to authenticate with (PEM format).

redisearch.key-password

Password of the private key file, or null if it’s not password-protected.

redisearch.cert-path

X.509 certificate chain file to authenticate with (PEM format).

4. SQL support

4.1. Tables and columns

Each Redis Query Engine index is a table in the default schema (see redisearch.default-schema-name). A table has these columns:

  • One per indexed field, named by its attribute (the AS name for JSON paths).

  • One per field that isn’t indexed but appears in the first 10 documents returned by FT.SEARCH <index> *.

  • For JSON indexes, a $ column holding the whole document as JSON text.

  • A hidden key column holding the document’s Redis key. Hidden columns are left out of SELECT *, so name it: SELECT key, * FROM beers.

Table 4. Type mapping
Redis field type Trino type

NUMERIC

DOUBLE

TAG, TEXT, GEO, GEOSHAPE, VECTOR

VARCHAR

Not indexed

VARCHAR

After FT.CREATE over existing keys, or ALTER TABLE ... ADD COLUMN (which runs FT.ALTER), Redis indexes the documents in the background. Until it finishes, queries on that index fail with REDISEARCH_INDEX_NOT_READY (Index beers is still being built (42% indexed) ...) instead of returning incomplete results. Retry once FT.INFO reports indexing as 0. CREATE TABLE creates its index with SKIPINITIALSCAN, so a new table can be queried right away.

4.2. Statements

Table 5. Supported statements
Statement Notes

SELECT

All of Trino’s query syntax, including joins (also across catalogs), subqueries, WITH, UNION, DISTINCT, GROUP BY, ORDER BY and window functions. Pushdown describes which parts run in Redis.

SHOW SCHEMAS, SHOW TABLES, SHOW COLUMNS, DESCRIBE, SHOW CREATE TABLE, information_schema

SHOW TABLES lists the indexes returned by FT._LIST.

EXPLAIN

The table scan shows the filters, limit and aggregations sent to Redis.

CREATE TABLE

Creates a hash index named after the table, with key prefix <table>:. See column types. IF NOT EXISTS is supported.

CREATE TABLE AS SELECT

Columns get the same field types as in CREATE TABLE. A query with a column of another type fails before the table is created.

INSERT, INSERT ... SELECT

Hash indexes only: the connector writes hashes, which an index on JSON documents never sees, so it fails on a JSON index. Each row is a new hash with key <prefix><ULID>, where <prefix> is the index’s first key prefix.

UPDATE

Hash indexes only. Setting a column to NULL removes the field from the hash.

DELETE

Deletes the matching keys, on hash and JSON indexes.

MERGE

Hash indexes only, except that WHEN MATCHED THEN DELETE also works on JSON indexes.

ALTER TABLE ... ADD COLUMN

Adds a field to the index with FT.ALTER. Columns are always added at the end. Queries on the table fail until Redis finishes reindexing its documents.

DROP TABLE

Drops the index and deletes its documents (FT.DROPINDEX ... DD).

These statements fail with a This connector does not support ... error:

  • CREATE SCHEMA, DROP SCHEMA, ALTER SCHEMA

  • CREATE OR REPLACE TABLE

  • ALTER TABLE ... RENAME TO, DROP COLUMN, RENAME COLUMN, ALTER COLUMN ... SET DATA TYPE

  • TRUNCATE

  • COMMENT ON

  • CREATE VIEW, CREATE MATERIALIZED VIEW

  • Queries on table versions (FOR VERSION AS OF, FOR TIMESTAMP AS OF)

Writes also fail when fault-tolerant execution is enabled (retry-policy other than NONE).

Table 6. Column types in CREATE TABLE
Trino type Index field Read back as

BIGINT, INTEGER, SMALLINT, TINYINT, DOUBLE, REAL, DECIMAL

NUMERIC

DOUBLE

TIMESTAMP(3), TIMESTAMP(3) WITH TIME ZONE

NUMERIC

DOUBLE, in epoch milliseconds

VARCHAR, CHAR, UUID

TAG

VARCHAR

BOOLEAN, DATE

TAG

VARCHAR: true or false, and ISO dates such as 2024-01-02

Other types, such as ARRAY, MAP, ROW, VARBINARY and TIME, fail with Unsupported column type. Because columns are read back from the index, a column declared as BIGINT becomes DOUBLE and one declared as BOOLEAN or DATE becomes VARCHAR, so later INSERT statements must supply values of those types. The TAG fields aren’t full-text TEXT fields. They’re CASESENSITIVE and split values into tags on the ASCII unit separator (\x1f) instead of ,, so Redis can prefilter = and IN on values containing commas, and doesn’t return rows that only differ in case.

4.3. Pushdown

Redis evaluates these parts of a query. Trino evaluates everything else on the rows Redis returns.

  • Filters on indexed fields, combined with AND:

    • =, IN, <, <=, >, >= and BETWEEN on NUMERIC fields.

    • = and IN on TAG fields, as a tag query. Redis splits stored values into tags on the field’s SEPARATOR (by default , on hashes and none on JSON), trims whitespace around each tag, and ignores case unless the field is CASESENSITIVE. It returns the documents with a tag that matches the value, and Trino keeps those equal to it. Trino evaluates the filter alone when a value contains the separator, starts or ends with whitespace, or has a control character other than whitespace, since a tag query can’t match it.

    • = and IN on TEXT fields, as a full-text query for the value’s words. Redis returns the documents containing all of them, and Trino keeps those equal to the value. Trino evaluates the filter alone when a value has only stop words, and for every TEXT field of an index created with its own STOPWORDS.

      Redis can’t match a missing field or compare strings, so Trino evaluates IS NULL, IS NOT NULL, a condition combined with OR ... IS NULL, and <>, <, > and BETWEEN on VARCHAR columns.

      Trino also evaluates LIKE. A Redis wildcard query matches single words of a TEXT field, ignores case on a TAG field without CASESENSITIVE, and leaves out documents once it has matched MAXEXPANSIONS (200 by default) distinct values.

  • count(), min, max, sum and avg on numeric columns, with or without GROUP BY, as FT.AGGREGATE with GROUPBY and REDUCE. If any aggregate in a query can’t be pushed down, such as count(DISTINCT ...) or count(column), or Trino filters the rows itself, as it does for filters on TAG and TEXT fields, Trino computes all of them. count(column) skips nulls, but Redis’s COUNT counts documents, so only count() is pushed down. Trino evaluates HAVING on the groups Redis returns.

  • LIMIT, unless Trino filters the rows itself. Trino sorts ORDER BY ... LIMIT itself.

4.4. Known limitations

Queries known to return wrong results or fail are tracked as open issues labeled bug.

5. Clients

5.1. JDBC Driver

The Trino JDBC driver allows users to access Trino from Java-based applications, and other non-Java applications running in a JVM.

Refer to the Trino documentation for setup instructions.

The following is an example of a JDBC URL used to create a connection to Redis SQL Trino:

jdbc:trino://example.net:8080/redisearch/default

5.2. Tableau

Refer to the Tableau documentation for setup instructions.

5.3. Trino CLI

Refer to the Trino CLI documentation for setup instructions.

6. Build

Run these commands to build the Trino connector for RediSearch from source (requires Java 25+):

git clone https://github.com/redis-field-engineering/redis-sql-trino.git
cd Redis SQL Trino
./mvnw clean package -DskipTests

7. Complete Walkthrough

Follow these step-by-step instructions to deploy a single-node Trino server on Ubuntu.

7.1. Install Java

Trino requires a 64-bit version of Java 25. It is recommended to use Azul Zulu as the JDK.

$ java -version
openjdk version "25.0.1" 2025-10-21 LTS
OpenJDK Runtime Environment Zulu25.30+17-CA (build 25.0.1+8-LTS)
OpenJDK 64-Bit Server VM Zulu25.30+17-CA (build 25.0.1+8-LTS, mixed mode, sharing)

7.2. Set up Trino

Download the Trino server tarball and unpack it.

wget https://repo1.maven.org/maven2/io/trino/trino-server/483/trino-server-483.tar.gz
mkdir /usr/lib/trino
tar xzvf trino-server-483.tar.gz --directory /usr/lib/trino --strip-components 1

Trino needs a data directory for storing logs, etc. It is recommended to create a data directory outside of the installation directory, which allows it to be easily preserved when upgrading Trino.

Create a data directory
mkdir -p /var/trino

Create an etc directory inside the installation directory to hold configuration files.

mkdir /usr/lib/trino/etc

Create a node.properties file.

/usr/lib/trino/etc/node.properties
node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/var/trino

Create a JVM config file.

/usr/lib/trino/etc/jvm.config
-server
-Xmx16G
-XX:InitialRAMPercentage=80
-XX:MaxRAMPercentage=80
-XX:G1HeapRegionSize=32M
-XX:+ExplicitGCInvokesConcurrent
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-XX:ReservedCodeCacheSize=512M
-XX:PerMethodRecompilationCutoff=10000
-XX:PerBytecodeRecompilationCutoff=10000
-Djdk.attach.allowAttachSelf=true
-Djdk.nio.maxCachedBufferSize=2000000
--add-modules=jdk.incubator.vector

Create a config properties file.

/usr/lib/trino/etc/config.properties
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
discovery.uri=http://localhost:8080

Create a logging configuration file.

/usr/lib/trino/etc/log.properties
io.trino=INFO

7.3. Set up Redis SQL Trino

Download latest release and unzip without any directory structure under plugin/redisearch:

wget https://github.com/redis-field-engineering/redis-sql-trino/releases/download/v0.4.0/redis-sql-trino-0.4.0.zip
unzip -j redis-sql-trino-0.4.0.zip -d /usr/lib/trino/plugin/redisearch

Create a etc/catalog subdirectory:

mkdir /usr/lib/trino/etc/catalog

Create a RediSearch connector configuration file:

/usr/lib/trino/etc/catalog/redisearch.properties
connector.name=redisearch
redisearch.uri=redis://localhost:6379

Change and/or add properties as needed.

7.4. Start Trino

Start the Trino server:

/usr/lib/trino/bin/launcher run

7.5. Run Trino CLI

Download and run trino-cli-483-executable.jar:

wget https://repo1.maven.org/maven2/io/trino/trino-cli/483/trino-cli-483-executable.jar -O /usr/local/bin/trino
chmod +x /usr/local/bin/trino
trino --catalog redisearch --schema default

Run a SQL query:

trino:default> select * from mySearchIndex;