Back to the README. Detailed SQL capabilities, statement execution, streaming and resource limits. Availability depends on the build profile.
| Feature | Support |
|---|---|
Queries (CommandStatementQuery), updates (CommandStatementUpdate) |
Yes. A statement without a row count (DDL, SET) reports 0 rows |
| Prepared statements, with parameters | Yes. The handle carries the SQL and the bound values, so the server keeps no state. Clients must use the handle a bind returns (DoPutPreparedStatementResult, Flight SQL's stateless prepared statements). arrow-go, the ADBC Flight SQL driver and the JDBC driver do, and are tested; a client that ignores it loses the bound values. The parameter schema gives each parameter the type it's used as (a compared column's, an INSERT target's, a CAST's, …), as the Redis ADBC driver infers it, or NULL. Parameters for a query are limited to 1 MiB |
Bulk ingest (CommandStatementIngest) |
Yes: create, append, replace, create-or-append, and pass-through options such as adbc.redis.ingest.index_columns. Temporary tables (temporary, or the pg_temp schema) need a session. adbc.ingest.* options are refused: set the target and mode with the command's fields |
GetCatalogs, GetDbSchemas, GetTables (with schemas), GetTableTypes, GetSqlInfo, GetXdbcTypeInfo |
Yes. The catalog is redis; schemas are key namespaces (public by default) |
| Primary and foreign keys | Empty results: the driver has no primary/foreign-key constraints |
Sessions: SetSessionOptions, GetSessionOptions, CloseSession |
Yes, for clients that keep cookies: see Sessions |
| Explicit query cancellation | CancelFlightInfo; the deprecated Flight SQL CancelQuery is translated to it. Applies to read-only query tickets with cancellation metadata; see cancellation details |
| Transactions, savepoints, Substrait | No |
How statements run:
- Read-only statements (
SELECT,SHOW) run when their ticket is read, so any server replica can serve the ticket. - Every other statement (
INSERT,UPDATE, DDL,SET, …) runs when its FlightInfo is requested, so it runs exactly once even if the client never reads the stream (DB-API cursors often don't) or reads it twice. The result, such as the rows ofINSERT … RETURNING, travels in the ticket. If it is larger than 1 MiB, it is kept in Redis for 10 minutes instead. - Outside a session, each request uses a pooled ADBC
connection. Session state then doesn't carry over between requests.
A statement that changes it (
SET,BEGIN,CREATE TEMP TABLE, or a table or view created inpg_temp) works within its own script, for exampleSET TIME ZONE 'Asia/Tokyo'; SELECT …, and its connection is closed afterwards rather than reused. - Plain scans stream from Redis. For a query that reads one table
through its index, row by row (
SELECT * FROM t, or a filter andORDER BYthe index can do), the driver reads the rows a cursor page at a time while they are sent. The server then holds about one batch of them, whatever the table's size. Other queries (aggregates, joins,DISTINCT, window functions, sorts the driver does) are built whole in memory first. The driver's Streamed results has the exact rules.- A streaming result keeps its pooled connection until it has been sent,
or the client goes away. Each Redis user can have
--max-streams(8) results streaming at once, but always fewer than--pool-max-open, so the user's other requests have a connection (with a pool of 1, nothing streams). With--auth=none, every client is the same user. Queries beyond that are read whole (see below), as are queries in a session that has made temporary tables or views. - A streaming result also keeps a cursor open on its table's index.
RediSearch allows an index
search-index-cursor-limitopen cursors (128 by default), and the driver reads every query through one, so at the limit every query on the table fails withRESOURCE_EXHAUSTEDuntil some are closed; clients can retry. The limit is shared by every client of the index: other servers (replicas), other tools, and every Redis user. So each server streams at most--max-table-streams(32) results from one table at once, across all users, and reads the rest whole. - On standalone Redis, the server also reads how many cursors the
index has open (
FT.INFO, at most once a second per table), counting every client, and stops streaming from the table once three quarters ofsearch-index-cursor-limitare open. The last quarter is left for queries read whole and other clients' short reads. A raised limit is picked up by itself. - On a cluster,
FT.INFOdoesn't report the count, so with several replicas keep their total--max-table-streamsunder the limit, or raisesearch-index-cursor-limitin Redis (and then--max-table-streams). - Set
--stream-overflow=reject(FLIGHT_STREAM_OVERFLOW=reject) to refuse an eligible scan withRESOURCE_EXHAUSTEDbefore execution when no stream/cursor slot is available. Retry after a stream finishes. The defaultbufferpreserves the behavior below. This option does not bound driver execution memory for joins, aggregates or other non-streaming queries. - A query that could stream but finds no stream free (past
--max-streamsor--max-table-streams, or with the index near its cursor limit) is read into memory before it is sent, and its connection and cursor are given back at once. Such results share--result-memory(1 GiB) across the server until they have been sent. One that doesn't fit fails withRESOURCE_EXHAUSTEDas soon as it would go over, and clients can retry, or read fewer rows or columns. - A client that takes longer than
--stream-stall-timeout(2 minutes) to read a batch gets aDEADLINE_EXCEEDEDerror instead of the rest, and the server stops reading from Redis. Redis deletes a cursor that isn't read for 5 minutes. - To read every result whole instead, pass
-adbc-option adbc.redis.stream_results=false.
- A streaming result keeps its pooled connection until it has been sent,
or the client goes away. Each Redis user can have
- Batches are sent at about 2 MiB each, under gRPC's default 4 MiB limit.