Skip to content

Redis catalog: How to use the raw decoder to correctly query the predefined BIGINT type value? #25928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
zhangbutao opened this issue Jun 4, 2025 · 0 comments

Comments

@zhangbutao
Copy link
Contributor

Here is my test:

  1. Set redis key/value through redis-cli
127.0.0.1:6379> SET testdb:testrawint:aa 123456789
OK
  1. Create trino-redis catalog
connector.name=redis
redis.nodes=127.0.0.1:6379
redis.password=psswd
redis.table-description-cache-ttl=1s
redis.table-description-dir=/etc/redis_raw_test

redis.key-prefix-schema-table=true

  1. Create redis raw decoder json definition file
    Refer to https://trino.io/docs/current/connector/kafka.html#raw-encoder
    cat /etc/redis_raw_test/testraw.json
{
   "tableName": "testrawint",
   "schemaName": "testdb",
   "key": {
       "dataFormat": "raw",
              "fields": [
            {
                "name":"redis_key",
                "type":"VARCHAR",
                "hidden":"false"
           }
       ]
   },
   "value": {
       "dataFormat": "raw",
       "fields": [
           {
                "name":"id",
                "mapping":"0",
                "dataFormat": "LONG",
                "type":"BIGINT"
           }

       ]
    }
}
  1. Query this redis key/value using tino-cli
trino> select * from redisraw.testdb.testrawint;
      redis_key       |         id
----------------------+---------------------
 testdb:testrawint:aa | 3544952156018063160
(1 row)

You will find that id is 3544952156018063160 instead of 123456789

  1. Change the json definition file to replace type BIGINT to VARCHAR
{
   "tableName": "testrawint",
   "schemaName": "testdb",
   "key": {
       "dataFormat": "raw",
              "fields": [
            {
                "name":"redis_key",
                "type":"VARCHAR",
                "hidden":"false"
           }
       ]
   },
   "value": {
       "dataFormat": "raw",
       "fields": [
           {
                "name":"id",
                "mapping":"0",
                "dataFormat": "BYTE",
                "type":"VARCHAR"
           }

       ]
    }
}

And then you can get the correct id value 123456789

trino> select * from redisraw.testdb.testrawint;
      redis_key       |    id
----------------------+-----------
 testdb:testrawint:aa | 123456789

Question

From the above test, i think trino-redis catalog can not use the raw decoder to query BIGINT/SMALLINT(or other numerical types) value.

This is because the Redis data in the test is always parsed into string type, and then the string type data is converted into bytes. If this byte is further converted into int type(or other numerical types), it will lead to incorrect results.

private void generateRowValues(String keyString, String valueString, @Nullable Map<String, String> hashValueMap)
{
byte[] keyData = keyString.getBytes(StandardCharsets.UTF_8);
byte[] stringValueData = valueString.getBytes(StandardCharsets.UTF_8);
// Redis connector supports two types of Redis values: STRING and HASH. HASH type requires hash row decoder to
// decode a row from map, whereas for the STRING type decoders are optional. The redis keyData is always byte array,
// so the decoder of key always decodes a row from bytes.
Optional<Map<DecoderColumnHandle, FieldValueProvider>> decodedKey = keyDecoder.decodeRow(keyData);
Optional<Map<DecoderColumnHandle, FieldValueProvider>> decodedValue = valueDecoder instanceof RedisRowDecoder redisRowDecoder
? redisRowDecoder.decodeRow(hashValueMap)
: valueDecoder.decodeRow(stringValueData);

return new RawValueProvider(ByteBuffer.wrap(value, start, actualEnd - start), fieldType, columnName, columnType);

public long getLong()
{
checkEnoughBytes();
return switch (fieldType) {
case BYTE -> value.get(start);
case SHORT -> value.getShort(start);
case INT -> value.getInt(start);
case LONG -> value.getLong(start);

So, I think trino-redis can only use the raw decoder to query the predefined VARCHAR type value.
WDYT?

https://trino.io/docs/current/connector/redis.html#raw-decoder BTW, the doc shows the raw-decoder can support numerical values. I think it should be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant