Tools
SQL function reference
Use type-aware SQL functions to inspect and mutate Redis collections, streams, RedisJSON values, and grouped rows.
Varc SQL keeps every collection in one row. Type-aware functions read a bounded scalar fact from the row’s value without flattening the collection. Aggregates collapse those source rows after WHERE.
| Function | Redis type | Result |
|---|---|---|
CARDINALITY(value) |
string, hash, list, set, zset, stream, JSON | Integer or NULL |
HASH_GET(value, field) |
hash | Binary or NULL |
HASH_HAS(value, field) |
hash | Boolean |
LIST_GET(value, index) |
list | Binary or NULL |
LIST_CONTAINS(value, item) |
list | Boolean |
SET_CONTAINS(value, member) |
set | Boolean |
ZSET_SCORE(value, member) |
zset | Real or NULL |
STREAM_CONTAINS(value, field [, expected]) |
stream | Boolean |
JSON_VALUE(value, '$.path') |
RedisJSON | JSON scalar or NULL |
COUNT(*) |
any | Integer |
COUNT(expr) |
any scalar | Integer |
SUM(expr) |
numeric scalar | Integer, Real, or NULL |
AVG(expr) |
numeric scalar | Real or NULL |
MIN(expr) / MAX(expr) |
non-opaque scalar | Scalar or NULL |
The first argument must be the value column. Fields, members, items, expected values, and JSON paths are exact text or binary constants; a list index is an integer constant. Text constants are UTF-8 bytes and X'…' supplies arbitrary bytes.
Calling a function on a stable key of the wrong Redis type returns NULL, or false for the Boolean existence and membership functions. A key that expires, changes type, or produces an oversized result during evaluation is indeterminate instead; see Results and limits.
Collection mutation functions
Mutation functions are available only as the complete right-hand side of SET value = ... in an UPDATE. Their first argument must be the bare value column. Remaining arguments are evaluated against the original row.
| Function signature | Redis type | Effect |
|---|---|---|
HASH_SET(value, field, item [, field, item ...]) |
hash | Set one or more field/value pairs. |
HASH_DELETE(value, field [, field ...]) |
hash | Delete one or more fields. |
HASH_EXPIRE(value, field, ttl_ms_or_NULL) |
hash | Set, clear, or immediately expire one field’s TTL. |
LIST_PUSH(value, 'head'/'tail', item [, item ...]) |
list | Push values at the selected end. |
LIST_POP(value, 'head'/'tail') |
list | Pop one value from the selected end. |
LIST_SET(value, index, item) |
list | Replace the item at a Redis index. |
LIST_INSERT(value, 'before'/'after', pivot, item) |
list | Insert relative to an exact pivot value. |
LIST_REMOVE(value, count, item) |
list | Remove occurrences using Redis LREM count semantics. |
LIST_TRIM(value, start, stop) |
list | Keep the inclusive Redis index range. |
SET_ADD(value, member [, member ...]) |
set | Add one or more exact members. |
SET_REMOVE(value, member [, member ...]) |
set | Remove one or more exact members. |
ZSET_SET(value, member, score [, member, score ...]) |
zset | Add or replace member scores. |
ZSET_INCREMENT(value, member, delta) |
zset | Increment one member by a finite number. |
ZSET_REMOVE(value, member [, member ...]) |
zset | Remove one or more members. |
STREAM_ADD(value, id, field, item [, field, item ...]) |
stream | Append an entry at id, including *. |
STREAM_DELETE(value, id [, id ...]) |
stream | Delete one or more entry IDs. |
STREAM_TRIM_MAXLEN(value, max_len [, approximate [, limit]]) |
stream | Trim by maximum length. |
STREAM_TRIM_MINID(value, min_id [, approximate [, limit]]) |
stream | Trim entries older than an ID. |
JSON_SET(value, path, json) |
RedisJSON | Store one JSON-encoded value at a path. |
JSON_DELETE(value, path) |
RedisJSON | Delete a path. |
JSON_ARRAY_APPEND(value, path, json [, json ...]) |
RedisJSON | Append JSON-encoded values to an array. |
JSON_ARRAY_INSERT(value, path, index, json [, json ...]) |
RedisJSON | Insert JSON-encoded values at an array index. |
JSON_ARRAY_POP(value, path, index) |
RedisJSON | Remove the array item at an index. |
Fields, items, members, IDs, paths, and JSON payloads accept text or binary scalar expressions. Text is encoded as UTF-8 and X'…' supplies arbitrary bytes. Indexes, counts, lengths, and optional stream trim limits require integer expressions; sorted-set scores and increments accept finite Integer or Real values. The optional stream approximate argument is Boolean.
HASH_EXPIRE(..., NULL) persists the field. A positive field TTL sets a relative lifetime in milliseconds, while zero or a negative value expires the field immediately. It requires server support for hash-field expiry. JSON mutations require RedisJSON, and their json arguments must contain valid JSON text.
UPDATE redis
SET value = SET_ADD(value, 'admin', 'verified')
WHERE key = 'user:42:roles' AND type = 'set'
RETURNING key, CARDINALITY(value) AS role_count;
UPDATE redis
SET value = STREAM_TRIM_MAXLEN(value, 10000, TRUE, 1000)
WHERE key LIKE 'events:%' AND type = 'stream'
LIMIT 50;
A wrong-type mutation fails the current key and stops the statement. It never converts or recreates the key as another type. See Update keys with SQL for commit and error behavior.
CARDINALITY
CARDINALITY(value) -> integer | NULL
Returns a string’s byte length; a hash, list, set, or sorted set’s item count; a stream’s entry count; or the child count of a top-level JSON object or array. A top-level JSON scalar and an unknown type return NULL.
SELECT key, type, CARDINALITY(value) AS size
FROM redis
WHERE CARDINALITY(value) >= 100
ORDER BY size DESC
LIMIT 50;
HASH_GET
HASH_GET(value, field) -> binary | NULL
Returns the exact bytes stored at field. It returns NULL when the field is absent or the key is not a hash.
SELECT key, HASH_GET(value, 'email') AS email
FROM redis
WHERE type = 'hash'
AND HASH_GET(value, 'email') LIKE '%@example.com'
LIMIT 100;
HASH_HAS
HASH_HAS(value, field) -> boolean
Returns true when the hash contains field. An absent field or a stable non-hash value returns false.
SELECT key
FROM redis
WHERE type = 'hash'
AND HASH_HAS(value, 'last_login')
LIMIT 100;
LIST_GET
LIST_GET(value, index) -> binary | NULL
Returns one list item using Redis indexing. Index 0 is the first item and negative indexes count from the end. An out-of-range index or stable non-list value returns NULL.
SELECT key, LIST_GET(value, 0) AS first, LIST_GET(value, -1) AS last
FROM redis
WHERE type = 'list'
LIMIT 100;
LIST_CONTAINS
LIST_CONTAINS(value, item) -> boolean
Returns true when a list contains the exact byte value. A stable non-list value returns false. The connected server must support Redis LPOS; Varc reports the function as unsupported before execution when it does not.
SELECT key
FROM redis
WHERE type = 'list'
AND LIST_CONTAINS(value, X'00646F6E65')
LIMIT 100;
SET_CONTAINS
SET_CONTAINS(value, member) -> boolean
Tests exact set membership. A missing member or stable non-set value returns false.
SELECT key
FROM redis
WHERE type = 'set'
AND SET_CONTAINS(value, 'admin')
LIMIT 100;
ZSET_SCORE
ZSET_SCORE(value, member) -> real | NULL
Returns a finite sorted-set score. A missing member or stable non-sorted-set value returns NULL.
SELECT key, ZSET_SCORE(value, 'daniel') AS score
FROM redis
WHERE type = 'zset'
AND ZSET_SCORE(value, 'daniel') >= 100
ORDER BY score DESC
LIMIT 50;
STREAM_CONTAINS
STREAM_CONTAINS(value, field) -> boolean
STREAM_CONTAINS(value, field, expected) -> boolean
Searches bounded XRANGE windows. With two arguments it returns true when any entry contains field; with three, the same entry must contain the exact field/value pair. A stable non-stream value returns false.
False is final only after the stream traversal completes. A large stream can pause at a segment budget; choose Continue to resume from the retained stream position.
SELECT key
FROM redis
WHERE type = 'stream'
AND STREAM_CONTAINS(value, 'status', 'failed')
LIMIT 100;
JSON_VALUE
JSON_VALUE(value, '$.path') -> json scalar | NULL
The path must be a constant valid JSONPath beginning with $. The result preserves JSON null, Boolean, string, integer, or real type. A missing path, multiple matches, an object or array result, or a stable non-JSON value returns SQL NULL.
The connected Redis server must provide RedisJSON. If it does not, a query that uses JSON_VALUE fails its capability check instead of pretending the data is absent.
SELECT key, JSON_VALUE(value, '$.age') AS age
FROM redis
WHERE type = 'json'
AND JSON_VALUE(value, '$.age') > 30
ORDER BY age DESC NULLS LAST
LIMIT 50;
COUNT
COUNT(*) -> integer
COUNT(expr) -> integer
COUNT(*) counts source rows that pass WHERE. COUNT(expr) counts non-NULL arguments. Empty global input returns 0. NULL aggregate inputs are ignored. An indeterminate argument poisons only that aggregate.
SELECT type, COUNT(*) AS keys
FROM redis
GROUP BY type
ORDER BY keys DESC
LIMIT 20;
SUM
SUM(expr) -> integer | real | NULL
Adds numeric arguments with checked integer or finite real arithmetic. Empty grouped input yields no row; empty global input returns NULL.
AVG
AVG(expr) -> real | NULL
Averages numeric arguments from retained sum and count. Empty input returns NULL.
MIN and MAX
MIN(expr) -> scalar | NULL
MAX(expr) -> scalar | NULL
Compare non-opaque scalars with the same rules as ORDER BY. Opaque collections are rejected. Empty input returns NULL.
Unsupported aggregate modifiers include DISTINCT, FILTER, ordered or named arguments, nesting, and OVER.