Skip to content

Problem accessing varint in scylla when value > 32767 #49

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
A-Posthuman opened this issue Jun 12, 2024 · 2 comments
Open

Problem accessing varint in scylla when value > 32767 #49

A-Posthuman opened this issue Jun 12, 2024 · 2 comments

Comments

@A-Posthuman
Copy link

A-Posthuman commented Jun 12, 2024

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
Copy link
Author

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.

@s3rius
Copy link
Member

s3rius commented Apr 2, 2025

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())

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

No branches or pull requests

2 participants