Fix value skipping with counter columns

patch by Sylvain Lebresne; reviewed by Aleksey Yeschenko for
CASSANDRA-11726


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/ee609411
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/ee609411
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/ee609411

Branch: refs/heads/cassandra-3.8
Commit: ee609411a8e154255812b157788a79bbdf076566
Parents: 02ebf87
Author: Sylvain Lebresne <sylv...@datastax.com>
Authored: Thu Aug 4 17:54:03 2016 +0200
Committer: Aleksey Yeschenko <alek...@apache.org>
Committed: Tue Aug 9 16:33:10 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 src/java/org/apache/cassandra/db/Conflicts.java |  9 +++++++
 .../cql3/validation/entities/CountersTest.java  | 27 ++++++++++++++++++++
 3 files changed, 37 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee609411/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 2c5c221..b7bbf72 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.9
+ * Fix value skipping with counter columns (CASSANDRA-11726)
  * Fix nodetool tablestats miss SSTable count (CASSANDRA-12205)
  * Fixed flacky SSTablesIteratedTest (CASSANDRA-12282)
  * Fixed flacky SSTableRewriterTest: check file counts before calling 
validateCFS (CASSANDRA-12348)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee609411/src/java/org/apache/cassandra/db/Conflicts.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Conflicts.java 
b/src/java/org/apache/cassandra/db/Conflicts.java
index fa0e819..9e8bd9a 100644
--- a/src/java/org/apache/cassandra/db/Conflicts.java
+++ b/src/java/org/apache/cassandra/db/Conflicts.java
@@ -68,6 +68,15 @@ public abstract class Conflicts
         if (!rightLive)
             return Resolution.RIGHT_WINS;
 
+        // Handle empty values. Counters can't truly have empty values, but we 
can have a counter cell that temporarily
+        // has one on read if the column for the cell is not queried by the 
user due to the optimization of #10657. We
+        // thus need to handle this (see #11726 too).
+        if (!leftValue.hasRemaining())
+            return rightValue.hasRemaining() || leftTimestamp > rightTimestamp 
? Resolution.LEFT_WINS : Resolution.RIGHT_WINS;
+
+        if (!rightValue.hasRemaining())
+            return Resolution.RIGHT_WINS;
+
         return Resolution.MERGE;
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee609411/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java 
b/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java
index 33b4a4f..b1cd0bb 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java
@@ -196,4 +196,31 @@ public class CountersTest extends CQLTester
         assertInvalidThrowMessage("counter type is not supported for PRIMARY 
KEY part a",
                                   InvalidRequestException.class, 
String.format("CREATE TABLE %s.%s (a counter, b int, PRIMARY KEY (b, a)) WITH 
CLUSTERING ORDER BY (a desc);", KEYSPACE, createTableName()));
     }
+
+    /**
+     * Test for the bug of #11726.
+     */
+    @Test
+    public void testCounterAndColumnSelection() throws Throwable
+    {
+        for (String compactStorageClause : new String[]{ "", " WITH COMPACT 
STORAGE" })
+        {
+            createTable("CREATE TABLE %s (k int PRIMARY KEY, c counter)" + 
compactStorageClause);
+
+            // Flush 2 updates in different sstable so that the following 
select does a merge, which is what triggers
+            // the problem from #11726
+
+            execute("UPDATE %s SET c = c + ? WHERE k = ?", 1L, 0);
+
+            flush();
+
+            execute("UPDATE %s SET c = c + ? WHERE k = ?", 1L, 0);
+
+            flush();
+
+            // Querying, but not including the counter. Pre-CASSANDRA-11726, 
this made us query the counter but include
+            // it's value, which broke at merge (post-CASSANDRA-11726 are 
special cases to never skip values).
+            assertRows(execute("SELECT k FROM %s"), row(0));
+        }
+    }
 }

Reply via email to