Details
-
Bug
-
Status: Resolved
-
Normal
-
Resolution: Fixed
-
None
-
Correctness
-
Normal
-
Normal
-
Code Inspection
-
All
-
None
-
Description
It is the semantic of CQL that a (CQL) row exists as long as it has one non-null column (including the PK columns).
To determine if a row has some non-null primary key, Cassandra relies on the row primary key liveness.
For example:
CREATE TABLE test (pk int, ck int, v int, PRIMARY KEY(pk, ck)); INSERT INTO test(pk, ck, v) VALUES (1, 1, 1); DELETE v FROM test WHERE pk = 1 AND ck = 1 SELECT v FROM test;
will return
v
---
null
UPDATE statements do not set the row primary key liveness by consequence if the user had used an UPDATE statement instead of an INSERT the SELECT query would not have returned any rows.
CASSANDRA-16226 introduced a regression by stopping early in the timestamp ordered logic if an UPDATE statement covering all the columns was found in an SSTable. As the row returned did not have a primary key liveness if another node was also returning a column deletion, the expected row will not be returned.
The problem can be reproduced with the following test:
@Test public void testSelectWithUpdatedColumnOnOneNodeAndColumnDeletionOnTheOther() throws Throwable { try (Cluster cluster = init(builder().withNodes(2).start())) { cluster.schemaChange(withKeyspace("CREATE TABLE %s.tbl (pk int, ck text, v int, PRIMARY KEY (pk, ck))")); cluster.get(1).executeInternal(withKeyspace("INSERT INTO %s.tbl (pk, ck, v) VALUES (1, '1', 1) USING TIMESTAMP 1000")); cluster.get(1).flush(KEYSPACE); cluster.get(1).executeInternal(withKeyspace("UPDATE %s.tbl USING TIMESTAMP 2000 SET v = 2 WHERE pk = 1 AND ck = '1'")); cluster.get(1).flush(KEYSPACE); cluster.get(2).executeInternal(withKeyspace("DELETE v FROM %s.tbl USING TIMESTAMP 3000 WHERE pk=1 AND ck='1'")); cluster.get(2).flush(KEYSPACE); assertRows(cluster.coordinator(2).execute(withKeyspace("SELECT * FROM %s.tbl WHERE pk=1 AND ck='1'"), ConsistencyLevel.ALL), row(1, "1", null)); // <-- FAIL assertRows(cluster.coordinator(2).execute(withKeyspace("SELECT v FROM %s.tbl WHERE pk=1 AND ck='1'"), ConsistencyLevel.ALL), row((Integer) null)); } }
Attachments
Issue Links
- is caused by
-
CASSANDRA-16226 COMPACT STORAGE SSTables created before 3.0 are not correctly skipped by timestamp due to missing primary key liveness info
- Resolved
- relates to
-
CASSANDRA-16686 Queries returning static content when the partition has no rows might fail to return some rows
- Resolved
-
CASSANDRA-16712 DROP COMPACT STORAGE does not invalidate prepared statements as it should
- Resolved
-
CASSANDRA-16675 Preserve Query Performance with ClusteringIndexNamesFilter After Running DROP COMPACT STORAGE
- Open