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");
+ }
+ }
}