scyllapy icon indicating copy to clipboard operation
scyllapy copied to clipboard

Problem accessing varint in scylla when value > 32767

Open A-Posthuman opened this issue 1 year ago • 2 comments
trafficstars

I have a table where one of the primary key cols is a varint, with possible values up to 999999. At first I couldn't get scyllapy to work at all when trying to do a parameterized SELECT on this table, I kept getting back "[]" as the result.all(). It would work with a simple string non-parameterized query.

Eventually I tracked this down to some kind of problem with how scyllapy is handling ints. I found for values below 128 if I wrap the int in extra_types.TinyInt() then it works as a parameter. For values between 128 to 32767 I can use extra_types.SmallInt(). However when I try to use extra_types.BigInt() for values > 32767 it fails and I get back "[]" again as the result.

All attempts I made to pass a plain python int value as a parameter, whether directly in an execute() call, in a Query or PreparedQuery, etc. all seem to fail. They only work when I wrap them in one of the extra_types. How can I get this to work with values > 32767?

A-Posthuman avatar Jun 12 '24 22:06 A-Posthuman

For anyone running into this, I found that using struct to pack the desired int into a 3-byte big-endian (despite my servers being little endian, I think this has something to do with "network packing"? or something about how Scylla deals with varints?) by using struct's 4-byte packing and then taking only the last 3 bytes, it works:

param_varint_greater_than_32767 = struct.pack('>i', 999999)[1:]

If there is some better way to do this that I missed, let me know.

A-Posthuman avatar Jul 09 '24 22:07 A-Posthuman

Hello. I have tried using bigint on current version and it works on biggest possible bigint value.

import asyncio

from scyllapy import Scylla, extra_types as et


async def main() -> None:
    """None."""
    scylla = Scylla(["localhost"])
    await scylla.startup()

    await scylla.execute(
        "CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = "
        "{'class': 'SimpleStrategy', 'replication_factor': 1};",
    )
    await scylla.use_keyspace("test")

    await scylla.execute("DROP TABLE IF EXISTS test;")
    await scylla.execute("CREATE TABLE IF NOT EXISTS test (id VARINT PRIMARY KEY);")

    await scylla.execute(
        "INSERT INTO test (id) VALUES (?);",
        [et.BigInt(9223372036854775807)],
    )
    rows = await scylla.execute("SELECT * FROM test;")
    for row in rows.all():
        print(row)


if __name__ == "__main__":
    asyncio.run(main())

s3rius avatar Apr 02 '25 00:04 s3rius