From c12abfb697dabd249c37b578bde675c0f52d4e34 Mon Sep 17 00:00:00 2001 From: Carl Yeksigian Date: Fri, 11 Sep 2015 11:18:23 +0200 Subject: [PATCH] Make aggregates work with reversed types patch by Carl Yeksigian; reviewed by Benjamin Lerer for CASSANDRA-10296 --- .../apache/cassandra/cql3/selection/Selector.java | 4 ++++ .../apache/cassandra/db/marshal/AbstractType.java | 5 +++++ .../apache/cassandra/db/marshal/ReversedType.java | 6 ++++++ .../cql3/validation/entities/UFTest.java | 15 +++++++++++++++ .../validation/operations/AggregationTest.java | 12 ++++++++++++ 5 files changed, 42 insertions(+) diff --git a/src/java/org/apache/cassandra/cql3/selection/Selector.java b/src/java/org/apache/cassandra/cql3/selection/Selector.java index d53fba1bd5..1bddcc8846 100644 --- a/src/java/org/apache/cassandra/cql3/selection/Selector.java +++ b/src/java/org/apache/cassandra/cql3/selection/Selector.java @@ -27,6 +27,7 @@ import org.apache.cassandra.cql3.ColumnSpecification; import org.apache.cassandra.cql3.functions.Function; import org.apache.cassandra.cql3.selection.Selection.ResultSetBuilder; import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.ReversedType; import org.apache.cassandra.exceptions.InvalidRequestException; /** @@ -180,6 +181,9 @@ public abstract class Selector implements AssignmentTestable if (getType().isFrozenCollection()) receiverType = receiverType.freeze(); + if (getType().isReversed()) + receiverType = ReversedType.getInstance(receiverType); + if (receiverType.equals(getType())) return AssignmentTestable.TestResult.EXACT_MATCH; diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java b/src/java/org/apache/cassandra/db/marshal/AbstractType.java index aa25a81dd6..ab0564226f 100644 --- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java +++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java @@ -155,6 +155,11 @@ public abstract class AbstractType implements Comparator return isCollection() && !isMultiCell(); } + public boolean isReversed() + { + return false; + } + public static AbstractType parseDefaultParameters(AbstractType baseType, TypeParser parser) throws SyntaxException { Map parameters = parser.getKeyValueParameters(); diff --git a/src/java/org/apache/cassandra/db/marshal/ReversedType.java b/src/java/org/apache/cassandra/db/marshal/ReversedType.java index 2181f74002..2aea3cd07b 100644 --- a/src/java/org/apache/cassandra/db/marshal/ReversedType.java +++ b/src/java/org/apache/cassandra/db/marshal/ReversedType.java @@ -128,6 +128,12 @@ public class ReversedType extends AbstractType return baseType.getSerializer(); } + @Override + public boolean isReversed() + { + return true; + } + @Override public String toString() { diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java index 2e7c2f1ac1..673ccc3231 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java @@ -428,6 +428,21 @@ public class UFTest extends CQLTester assertEmpty(execute("SELECT v FROM %s WHERE v=" + fRepeat + "(?, ?)", "a", 2)); } + @Test + public void testFunctionExecutionWithReversedTypeAsOutput() throws Throwable + { + createTable("CREATE TABLE %s (k int, v text, PRIMARY KEY(k, v)) WITH CLUSTERING ORDER BY (v DESC)"); + + String fRepeat = createFunction(KEYSPACE_PER_TEST, "text", + "CREATE FUNCTION %s(v text) " + + "RETURNS NULL ON NULL INPUT " + + "RETURNS text " + + "LANGUAGE java " + + "AS 'return v + v;'"); + + execute("INSERT INTO %s(k, v) VALUES (?, " + fRepeat + "(?))", 1, "a"); + } + @Test public void testFunctionOverloading() throws Throwable { diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java index b44fc71452..b2ecd041bb 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java @@ -275,6 +275,18 @@ public class AggregationTest extends CQLTester assertInvalidSyntax("SELECT COUNT(2) FROM %s"); } + @Test + public void testReversedType() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, primary key (a, b)) WITH CLUSTERING ORDER BY (b DESC)"); + execute("INSERT INTO %s (a, b, c) VALUES (1, 1, 10)"); + execute("INSERT INTO %s (a, b, c) VALUES (1, 2, 9)"); + execute("INSERT INTO %s (a, b, c) VALUES (1, 3, 8)"); + execute("INSERT INTO %s (a, b, c) VALUES (1, 4, 7)"); + + assertRows(execute("SELECT max(c), min(c), avg(c) FROM %s WHERE a = 1 AND b > 1"), row(9, 7, 8)); + } + @Test public void testNestedFunctions() throws Throwable {