Skip to content

Commit

Permalink
cql3: create tokens out of null values properly
Browse files Browse the repository at this point in the history
Method reponsible for creating a token of given values is not meant to be
used with empty optionals. Thus, having requested a token of the columns
containing null values resulted with an exception being thrown. This kind
of behaviour was not compatible with the one applied in cassandra.

To fix this, before the computation of a token, it is checked whether
no null value is contained. If any value in the processed vector is null,
null value is returned.

Fixes:  #10594

Closes #10942
  • Loading branch information
Deexie authored and psarna committed Jul 4, 2022
1 parent 719724e commit bf34589
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cql3/functions/token_fct.hh
Expand Up @@ -32,6 +32,9 @@ public:
}

bytes_opt execute(cql_serialization_format sf, const std::vector<bytes_opt>& parameters) override {
if (std::any_of(parameters.cbegin(), parameters.cend(), [](const auto& param){ return !param; })) {
return std::nullopt;
}
auto key = partition_key::from_optional_exploded(*_schema, parameters);
auto tok = dht::get_token(*_schema, key);
warn(unimplemented::cause::VALIDATION);
Expand Down
14 changes: 14 additions & 0 deletions test/cql/token_from_null_test.cql
@@ -0,0 +1,14 @@
-- single null value
CREATE KEYSPACE reproducer WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
CREATE TABLE reproducer.t(pk int PRIMARY KEY, v int);
INSERT INTO reproducer.t (pk) VALUES (1);
SELECT TOKEN(v) FROM reproducer.t;

-- multiple null values
CREATE TABLE reproducer.t2(pk int PRIMARY KEY, a int, b int);
INSERT INTO reproducer.t2 (pk) VALUES (1);
SELECT TOKEN(pk, a, b) FROM reproducer.t2;
SELECT TOKEN(pk, b) FROM reproducer.t2;
SELECT TOKEN(a, b) FROM reproducer.t2;

DROP KEYSPACE reproducer;
39 changes: 39 additions & 0 deletions test/cql/token_from_null_test.result
@@ -0,0 +1,39 @@
> -- single null value
> CREATE KEYSPACE reproducer WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
OK
> CREATE TABLE reproducer.t(pk int PRIMARY KEY, v int);
OK
> INSERT INTO reproducer.t (pk) VALUES (1);
OK
> SELECT TOKEN(v) FROM reproducer.t;
+-------------------+
| system.token(v) |
|-------------------|
| null |
+-------------------+
>
> -- multiple null values
> CREATE TABLE reproducer.t2(pk int PRIMARY KEY, a int, b int);
OK
> INSERT INTO reproducer.t2 (pk) VALUES (1);
OK
> SELECT TOKEN(pk, a, b) FROM reproducer.t2;
+--------------------------+
| system.token(pk, a, b) |
|--------------------------|
| null |
+--------------------------+
> SELECT TOKEN(pk, b) FROM reproducer.t2;
+-----------------------+
| system.token(pk, b) |
|-----------------------|
| null |
+-----------------------+
> SELECT TOKEN(a, b) FROM reproducer.t2;
+----------------------+
| system.token(a, b) |
|----------------------|
| null |
+----------------------+
>
> DROP KEYSPACE reproducer;OK

0 comments on commit bf34589

Please sign in to comment.