You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sa...@apache.org on 2016/05/02 12:15:01 UTC

[2/3] cassandra git commit: Add support for filtering on counter columns

Add support for filtering on counter columns

Patch by Alex Petrov; reviewed by Sam Tunnicliffe for CASSANDRA-11629


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

Branch: refs/heads/trunk
Commit: c08eeafdcfe4b5d0fb1a8aa34ca5df27be7934ce
Parents: 620efdc
Author: Alex Petrov <ol...@gmail.com>
Authored: Tue Apr 26 18:10:38 2016 +0200
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Mon May 2 11:07:39 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../apache/cassandra/db/filter/RowFilter.java   | 22 ++++++
 .../cql3/validation/entities/CountersTest.java  | 74 ++++++++++++++++++++
 3 files changed, 97 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/c08eeafd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 64bcbd8..95f450b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.6
+ * Fix queries with filtering on counter columns (CASSANDRA-11629)
  * Improve tombstone printing in sstabledump (CASSANDRA-11655)
  * Fix paging for range queries where all clustering columns are specified (CASSANDRA-11669)
  * Don't require HEAP_NEW_SIZE to be set when using G1 (CASSANDRA-11600)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c08eeafd/src/java/org/apache/cassandra/db/filter/RowFilter.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/filter/RowFilter.java b/src/java/org/apache/cassandra/db/filter/RowFilter.java
index 4960452..8060f23 100644
--- a/src/java/org/apache/cassandra/db/filter/RowFilter.java
+++ b/src/java/org/apache/cassandra/db/filter/RowFilter.java
@@ -27,6 +27,7 @@ import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.Operator;
 import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.context.*;
 import org.apache.cassandra.db.marshal.*;
 import org.apache.cassandra.db.partitions.*;
 import org.apache.cassandra.db.rows.*;
@@ -611,6 +612,27 @@ public abstract class RowFilter implements Iterable<RowFilter.Expression>
                 case LTE:
                 case GTE:
                 case GT:
+                    {
+                        assert !column.isComplex() : "Only CONTAINS and CONTAINS_KEY are supported for 'complex' types";
+
+                        // In order to support operators on Counter types, their value has to be extracted from internal
+                        // representation. See CASSANDRA-11629
+                        if (column.type.isCounter())
+                        {
+                            ByteBuffer foundValue = getValue(metadata, partitionKey, row);
+                            if (foundValue == null)
+                                return false;
+
+                            ByteBuffer counterValue = LongType.instance.decompose(CounterContext.instance().total(foundValue));
+                            return operator.isSatisfiedBy(LongType.instance, counterValue, value);
+                        }
+                        else
+                        {
+                            // Note that CQL expression are always of the form 'x < 4', i.e. the tested value is on the left.
+                            ByteBuffer foundValue = getValue(metadata, partitionKey, row);
+                            return foundValue != null && operator.isSatisfiedBy(column.type, foundValue, value);
+                        }
+                    }
                 case NEQ:
                     {
                         assert !column.isComplex() : "Only CONTAINS and CONTAINS_KEY are supported for 'complex' types";

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c08eeafd/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 e54d105..89fd767 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/CountersTest.java
@@ -112,4 +112,78 @@ public class CountersTest extends CQLTester
                    row(1L) // no change to the counter value
         );
     }
+
+    @Test
+    public void testCounterFiltering() throws Throwable
+    {
+        for (String compactStorageClause: new String[] {"", " WITH COMPACT STORAGE"})
+        {
+            createTable("CREATE TABLE %s (k int PRIMARY KEY, a counter)" + compactStorageClause);
+
+            for (int i = 0; i < 10; i++)
+                execute("UPDATE %s SET a = a + ? WHERE k = ?", (long) i, i);
+
+            execute("UPDATE %s SET a = a + ? WHERE k = ?", 6L, 10);
+
+            // GT
+            assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE a > ? ALLOW FILTERING", 5L),
+                                    row(6, 6L),
+                                    row(7, 7L),
+                                    row(8, 8L),
+                                    row(9, 9L),
+                                    row(10, 6L));
+
+            // GTE
+            assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE a >= ? ALLOW FILTERING", 6L),
+                                    row(6, 6L),
+                                    row(7, 7L),
+                                    row(8, 8L),
+                                    row(9, 9L),
+                                    row(10, 6L));
+
+            // LT
+            assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE a < ? ALLOW FILTERING", 3L),
+                                    row(0, 0L),
+                                    row(1, 1L),
+                                    row(2, 2L));
+
+            // LTE
+            assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE a <= ? ALLOW FILTERING", 3L),
+                                    row(0, 0L),
+                                    row(1, 1L),
+                                    row(2, 2L),
+                                    row(3, 3L));
+
+            // EQ
+            assertRowsIgnoringOrder(execute("SELECT * FROM %s WHERE a = ? ALLOW FILTERING", 6L),
+                                    row(6, 6L),
+                                    row(10, 6L));
+        }
+    }
+
+    @Test
+    public void testCounterFilteringWithNull() throws Throwable
+    {
+        for (String compactStorageClause : new String[]{ "", " WITH COMPACT STORAGE" })
+        {
+            createTable("CREATE TABLE %s (k int PRIMARY KEY, a counter, b counter)" + compactStorageClause);
+            execute("UPDATE %s SET a = a + ? WHERE k = ?", 1L, 1);
+
+            assertRows(execute("SELECT * FROM %s WHERE a > ? ALLOW FILTERING", 0L),
+                       row(1, 1L, null));
+            // GT
+            assertEmpty(execute("SELECT * FROM %s WHERE b > ? ALLOW FILTERING", 1L));
+            // GTE
+            assertEmpty(execute("SELECT * FROM %s WHERE b >= ? ALLOW FILTERING", 1L));
+            // LT
+            assertEmpty(execute("SELECT * FROM %s WHERE b < ? ALLOW FILTERING", 1L));
+            // LTE
+            assertEmpty(execute("SELECT * FROM %s WHERE b <= ? ALLOW FILTERING", 1L));
+            // EQ
+            assertEmpty(execute("SELECT * FROM %s WHERE b = ? ALLOW FILTERING", 1L));
+            // with null
+            assertInvalidMessage("Invalid null value for counter increment/decrement",
+                                 "SELECT * FROM %s WHERE b = null ALLOW FILTERING");
+        }
+    }
 }