Skip to content
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

counters: Fix filtering of counters #6277

Merged
merged 2 commits into from Apr 27, 2020

Conversation

jul-stas
Copy link
Contributor

@jul-stas jul-stas commented Apr 23, 2020

Queries with ALLOW FILTERING and constraints on counter values used to be rejected as "unimplemented". The reason was a missing tri-comparator, which is added in this patch.

Fixes #5635

@jul-stas jul-stas changed the base branch from master to next April 23, 2020 16:44
types.cc Outdated
@@ -1985,8 +1985,15 @@ struct compare_visitor {
int32_t operator()(const empty_type_impl&) { return 0; }
int32_t operator()(const tuple_type_impl& t) { return compare_aux(t, v1, v2); }
int32_t operator()(const counter_type_impl&) {
fail(unimplemented::cause::COUNTERS);
return 0;
if (v1.empty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does empty value mean? Is it deleted counter or is it counter before the first operation? The second would mean empty value == 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Deleted counters do not get into this comparison (they are excluded on higher level). But uninitialized ones do - even for non-counter types. That's why e.g. ints also suffer from empty values:

cqlsh> CREATE TABLE ks.tbl_int2 (pk int primary key, i1 int, i2 int);
cqlsh> INSERT INTO ks.tbl_int2 (pk, i1) VALUES (0, 0);
cqlsh> SELECT * FROM ks.tbl_int2 WHERE i2 < -999 ALLOW FILTERING;

 pk | i1 | i2
----+----+------
  0 |  0 | null

(1 rows)

My thinking is that uninitialized values should never get that deep.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably right. For counters fix would be easy (uninitialized == 0) but for ints it's not that easy. We probably should fix this in the upper layer. But it might be easier to treat empty for counters as 0 in this PR and merge it and fix the null thing in separate PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uninitialized int is NULL, not zero. NULL doesn't equal anything.

For counters, it is reasonable to use 0 for an uninitialized counter (there is no way to initialize a counter).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does Cassanra do? e.g. for a table with two counter columns, perform an update that increments just one of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@avikivity Tested on C* 3.11:

  • untouched counter doesn't equal anything;
  • deleted counter doesn't equal anything.

I just updated this patch so Scylla treats untouched counters as zeros (and deleted ones as NULLs). Such a compatibility breach makes sense to me too, but we need a definitive opinion if it's OK.

test/cql/counters_test.cql Outdated Show resolved Hide resolved
@haaawk
Copy link
Contributor

haaawk commented Apr 24, 2020

LGTM in general. I have just one question and request for some additional test cases. Thanks.

CQL `counter_type_impl` is now made comparable by deserializing it
as an `int64_t`. It allows the use of counters in statement
restrictions.
Tested predicates: IN, EQ, GE, GT, LE, LT.
Untouched counters are expected to evaluate as 0.
Deleted counters are expected not to appear at all.
Copy link
Contributor

@haaawk haaawk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@haaawk haaawk requested a review from psarna April 27, 2020 11:40
@haaawk
Copy link
Contributor

haaawk commented Apr 27, 2020

@avikivity @psarna could any of you merge this in, please?

@psarna
Copy link
Contributor

psarna commented Apr 27, 2020

Looks good. Also, looks like the effort of adding all these if (counters) { throw unimplemented } checks was bigger than providing an actual implementation (:

@psarna psarna merged commit c32faee into scylladb:next Apr 27, 2020
@psarna
Copy link
Contributor

psarna commented Apr 27, 2020

I queued it as c32faee. It's debatable whether we should diverge from Cassandra's treatment of uninitialized counters, but our way seems to make more sense.

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

Successfully merging this pull request may close these issues.

Filtering on counter columns doesn't work (works in Cassandra 3.0)
4 participants