diff --git a/src/java/org/apache/cassandra/cql3/selection/Selector.java b/src/java/org/apache/cassandra/cql3/selection/Selector.java index 9990c2e83e..8d58d12d08 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 30d9ae9367..02a5539f5b 100644 --- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java +++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java @@ -225,6 +225,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 2e01d9bb97..2f4fdb7090 100644 --- a/src/java/org/apache/cassandra/db/marshal/ReversedType.java +++ b/src/java/org/apache/cassandra/db/marshal/ReversedType.java @@ -141,6 +141,12 @@ public class ReversedType extends AbstractType return baseType.valueLengthIfFixed(); } + @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 ce50767e41..bf3d33f1c0 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java @@ -423,6 +423,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 ed9277f6af..a1d0aab7dd 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java @@ -276,6 +276,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 {