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
Cannot Cast Counter To Double #14501
Comments
cc @cvybhu |
Thank you for the bug report. A switch case needs to be added here: scylladb/cql3/functions/castas_fcts.cc Lines 269 to 283 in 7d35cf8
As a temporary workaround, could you convert the value to |
Thanks for this, it's Grafana that is doing the queries so in that case unfortunately not. |
In
Maybe it's time to do that... @mykaul @eliransin we also need to do some soul-searching why we didn't find this bug much earlier:
Of course, now that we do know about this bug, we also need to fix it. |
I'm removing the "enhancement" tag - as the user noted, missing small details in CQL can break existing applications, and will be perceived by users as a bug, not a request for a new feature. |
Maybe they aren't a popular use case. I wonder what Grafana input is. |
@mykaul neither counters not casts are very "popular" features, so their combination is probably even less popular - but they do exist, and Grafana (which I didn't even know could use Cassandra as a backend, nice!) might not be the only Cassandra application that uses them. |
This bug is reproduced by the translated Cassandra unit test:
|
This is a translation of Cassandra's CQL unit test source file functions/CastFctsTest.java into our cql-pytest framework. There are 13 tests, 9 of them currently xfail. The failures are caused by one recently-discovered issue: Refs scylladb#14501: Cannot Cast Counter To Double and by three previously unknown or undocumented issues: Refs scylladb#14508: SELECT CAST column names should match Cassandra's Refs scylladb#14518: CAST from timestamp to string not same as Cassandra on zero milliseconds Refs scylladb#14522: Support CAST function not only in SELECT Curiously, the careful translation of this test also caused me to find a bug in Cassandra https://issues.apache.org/jira/browse/CASSANDRA-18647 which the test in Java missed because it made the same mistake as the implementation. Signed-off-by: Nadav Har'El <nyh@scylladb.com>
This is a translation of Cassandra's CQL unit test source file functions/CastFctsTest.java into our cql-pytest framework. There are 13 tests, 9 of them currently xfail. The failures are caused by one recently-discovered issue: Refs #14501: Cannot Cast Counter To Double and by three previously unknown or undocumented issues: Refs #14508: SELECT CAST column names should match Cassandra's Refs #14518: CAST from timestamp to string not same as Cassandra on zero milliseconds Refs #14522: Support CAST function not only in SELECT Curiously, the careful translation of this test also caused me to find a bug in Cassandra https://issues.apache.org/jira/browse/CASSANDRA-18647 which the test in Java missed because it made the same mistake as the implementation. Signed-off-by: Nadav Har'El <nyh@scylladb.com> Closes #14528
I could easily make the Cassandra test for counters work, but I think I opened Pandora's box :-( Even after I get So now I think that all these Recently in b25ee62 @wmitros also needed to deserialize counters and had to use weird workarounds because of these "unimplemented" things. I'm actually really worried that some of this code that reads counter, including the one that @wmitros wrote and I'm writing now, might be wrong. The code assumes that a counter is just a 64-bit integer. But isn't counter actually a complicated CRDT object, and needs to be "evaluated" to figure out the real count? I'm worried that my test (which increments a counter in memtable, so it might be short-circuited?) doesn't actually exercise this case. Or, maybe it's fine to read a counter as a 64-bit integer because we already have some other code which implicitly does the calculation when a counter object is converted to a 64-bit integer? The lua.cc has a comment saying "No data_value ever has a counter type, it is represented with long_type instead." I don't know if this is true and I can treat counter as a 64-bit integer. And if so, why is it an "abstract_type" instead of a "concrete_type" like the rest of the integer types? |
I ran into the same thing. I thought it's just a quick fix, but the They have to be implemented, but this requires much more work. |
The good news is that once I implemented all the methods by calling the |
There's something basic I don't understand. On-disk, a counter is some complicated thing with "shards" from different sstables, and so on. Am I correct in understanding that the representation in memory is always the sum of everything as just a uint64_type? If that's true, why isn't @avikivity @mykaul who is the expert in the counters column type in the company? |
Anything can be empty through ugly tricks (see |
No, counters are also represented as shards in memory too. But counters are conceptually a 64 bit integer, to calculate their value, you simply sum up all the shards. We also have another type of (legacy?) counter, that I found traces of in the code. I have no idea what that is, maybe that is the remains of an older implementation.
Sadly, all counter experts have left the company. So we are left with reverse-engineering the code. Some people (Avi) might remember why things are they way they are. I was always irked by how the counters were different then all the other types, with most regular type methods being unimplemented. My best guess is that this is simply due to we never getting around to properly finish this feature. I think it is time to remove all those nasty "unimplemented" traps. |
Counters are just bigints with a funny name on the coordinator side (there's a back door via CQL SCYLLA_COUNTER_SHARD_LIST) . They're only special on the replica. |
So Avi, is there a reason why counter_type cannot be an |
The actual type in the schema has to be different, otherwise we don't know it's a counter.
Yes. |
On second thought, I don't think a real counter can be "empty". Counters are written differently, and I don't see how an "empty" value can be written there. I wonder what happens, though, if you cast an "empty integer" (silly, but existing, concept) to other types, including counters. I guess yet another thing to test... |
We should deprecate emptys and auto-convert them to NULLs. |
I already have a working implementation that works well (and not too ugly) and will send a PR soon. As usual, as G. I. Joe said, "knowing is half the battle" - tests (which are the vast majority of the content of my patch) exposed weird corner cases and even more unimplemented functions I didn't find in the first try. |
It turns out (I wrote a test for this as well...) that neither Cassandra nor Scylla allow casting other types to "counter", so you can't cast an empty integer to a counter. Moreover, because of various limitations of CQL, I couldn't check what |
We were missing support in the "CAST(x AS type)" function for the counter type. This patch adds this support, as well as extensive testing that it works in Scylla the same as Cassandra. We also un-xfail an existing test translated from Cassandra's unit test. But note that this old test did not cover all the edge-cases that the new test checks - some missing cases in the implementation were not caught by the old test. Fixes scylladb#14501 Signed-off-by: Nadav Har'El <nyh@scylladb.com>
…adav Har'El We have had support for COUNTER columns for quite some time now, but some functionality was left unimplemented - various internal and CQL functions resulted in "unimplemented" messages when used, and the goal of this series is to fix those issues. The primary goal was to add the missing support for CASTing counters to other types in CQL (issue #14501), but we also add the missing CQL `counterasblob()` and `blobascounter()` functions (issue #14742). As usual, the series includes extensive functional tests for these features, and one pre-existing test for CAST that used to fail now begins to pass. Fixes #14501 Fixes #14742 Closes #14745 * github.com:scylladb/scylladb: test/cql-pytest: test confirming that casting to counter doesn't work cql: support casting of counter to other types cql: implement missing counterasblob() and blobascounter() functions cql: implement missing type functions for "counters" type
Any idea @nyh what release/when this fix will be released? |
@jonny7 it is already available in the nightly image so you can try that out right away. But it's not in any released version: It will be in the next open-source version but there is not schedule for when this will happen (it hasn't been branched yet). As I noted in #14501 (comment), I think we should consider this a compatibility bug, not a feature, so I want to backport it to the 5.2 and 5.1 branches. When I do that (stay tuned), you'll need to wait for the next 5.2.* or 5.1.* point releases to get this fix. |
This is a translation of Cassandra's CQL unit test source file functions/CastFctsTest.java into our cql-pytest framework. There are 13 tests, 9 of them currently xfail. The failures are caused by one recently-discovered issue: Refs #14501: Cannot Cast Counter To Double and by three previously unknown or undocumented issues: Refs #14508: SELECT CAST column names should match Cassandra's Refs #14518: CAST from timestamp to string not same as Cassandra on zero milliseconds Refs #14522: Support CAST function not only in SELECT Curiously, the careful translation of this test also caused me to find a bug in Cassandra https://issues.apache.org/jira/browse/CASSANDRA-18647 which the test in Java missed because it made the same mistake as the implementation. Signed-off-by: Nadav Har'El <nyh@scylladb.com> Closes #14528 (cherry picked from commit f08bc83)
…adav Har'El We have had support for COUNTER columns for quite some time now, but some functionality was left unimplemented - various internal and CQL functions resulted in "unimplemented" messages when used, and the goal of this series is to fix those issues. The primary goal was to add the missing support for CASTing counters to other types in CQL (issue #14501), but we also add the missing CQL `counterasblob()` and `blobascounter()` functions (issue #14742). As usual, the series includes extensive functional tests for these features, and one pre-existing test for CAST that used to fail now begins to pass. Fixes #14501 Fixes #14742 Closes #14745 * github.com:scylladb/scylladb: test/cql-pytest: test confirming that casting to counter doesn't work cql: support casting of counter to other types cql: implement missing counterasblob() and blobascounter() functions cql: implement missing type functions for "counters" type (cherry picked from commit a637ddd)
Backported to 5.2: |
This is a translation of Cassandra's CQL unit test source file functions/CastFctsTest.java into our cql-pytest framework. There are 13 tests, 9 of them currently xfail. The failures are caused by one recently-discovered issue: Refs #14501: Cannot Cast Counter To Double and by three previously unknown or undocumented issues: Refs #14508: SELECT CAST column names should match Cassandra's Refs #14518: CAST from timestamp to string not same as Cassandra on zero milliseconds Refs #14522: Support CAST function not only in SELECT Curiously, the careful translation of this test also caused me to find a bug in Cassandra https://issues.apache.org/jira/browse/CASSANDRA-18647 which the test in Java missed because it made the same mistake as the implementation. Signed-off-by: Nadav Har'El <nyh@scylladb.com> Closes #14528 (cherry picked from commit f08bc83) (cherry picked from commit e03c21a)
…adav Har'El We have had support for COUNTER columns for quite some time now, but some functionality was left unimplemented - various internal and CQL functions resulted in "unimplemented" messages when used, and the goal of this series is to fix those issues. The primary goal was to add the missing support for CASTing counters to other types in CQL (issue #14501), but we also add the missing CQL `counterasblob()` and `blobascounter()` functions (issue #14742). As usual, the series includes extensive functional tests for these features, and one pre-existing test for CAST that used to fail now begins to pass. Fixes #14501 Fixes #14742 Closes #14745 * github.com:scylladb/scylladb: test/cql-pytest: test confirming that casting to counter doesn't work cql: support casting of counter to other types cql: implement missing counterasblob() and blobascounter() functions cql: implement missing type functions for "counters" type (cherry picked from commit a637ddd) Small modification was needed to validate_visitor API for the patch to apply.
Backported to 5.1: Again I verified manually that all cql-pytest tests pass after the backport. After backporting to both 5.2 and 5.1, I will remove the "backport candidate" tag. |
Doc explicitly mention counter to double cast is supported https://opensource.docs.scylladb.com/stable/cql/functions.html#cast @nyh do we need to fix the docs in more places? |
This is Scylla's bug tracker, to be used for reporting bugs only.
If you have a question about Scylla, and not a bug, please ask it in
our mailing-list at scylladb-dev@googlegroups.com or in our slack channel.
Installation details
Scylla version (or git commit hash): 5.2.2
Cluster size: 3
OS (RHEL/CentOS/Ubuntu/AWS AMI):
Hardware details (for performance issues) Delete if unneeded
Platform (physical/VM/cloud instance type/docker): Docker / Kubernetes
Trying to
CAST
a Counter to a double fails withI've replicated this in Docker with version 5.1.7 + 5.2.2.
I've just tested this with Cassandra's latest Docker image too and it returns fine.
Thanks
The text was updated successfully, but these errors were encountered: