From 6093c2d99bd300eebe353ff05482924f38538e74 Mon Sep 17 00:00:00 2001 From: Stefan Miklosovic Date: Mon, 4 Nov 2024 14:06:42 +0100 Subject: [PATCH] Support UDTs and vectors as clustering keys in descending order patch by Stefan Miklosovic; reviewed by David Capwell for CASSANDRA-20050 --- CHANGES.txt | 1 + .../org/apache/cassandra/cql3/UserTypes.java | 12 +++++++----- .../cassandra/cql3/selection/Selectable.java | 2 +- .../cql3/validation/entities/UserTypesTest.java | 16 ++++++++++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 823be216cb..d8cab35210 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.0.15 + * Support UDTs and vectors as clustering keys in descending order (CASSANDRA-20050) * Fix CQL in snapshot's schema which did not contained UDTs used as reverse clustering columns (CASSANDRA-20036) * Add configurable batchlog endpoint strategies: random_remote, prefer_local, dynamic_remote, and dynamic (CASSANDRA-18120) * Fix bash-completion for debian distro (CASSANDRA-19999) diff --git a/src/java/org/apache/cassandra/cql3/UserTypes.java b/src/java/org/apache/cassandra/cql3/UserTypes.java index b023a8a0b8..df2e26fc47 100644 --- a/src/java/org/apache/cassandra/cql3/UserTypes.java +++ b/src/java/org/apache/cassandra/cql3/UserTypes.java @@ -41,7 +41,7 @@ public abstract class UserTypes public static ColumnSpecification fieldSpecOf(ColumnSpecification column, int field) { - UserType ut = (UserType)column.type; + UserType ut = (UserType)column.type.unwrap(); return new ColumnSpecification(column.ksName, column.cfName, new ColumnIdentifier(column.name + "." + ut.fieldName(field), true), @@ -132,7 +132,7 @@ public abstract class UserTypes { validateAssignableTo(keyspace, receiver); - UserType ut = (UserType)receiver.type; + UserType ut = (UserType)receiver.type.unwrap(); boolean allTerminal = true; List values = new ArrayList<>(entries.size()); int foundValues = 0; @@ -161,16 +161,18 @@ public abstract class UserTypes } } - DelayedValue value = new DelayedValue(((UserType)receiver.type), values); + DelayedValue value = new DelayedValue(((UserType)receiver.type.unwrap()), values); return allTerminal ? value.bind(QueryOptions.DEFAULT) : value; } private void validateAssignableTo(String keyspace, ColumnSpecification receiver) throws InvalidRequestException { - if (!receiver.type.isUDT()) + AbstractType unwrapped = receiver.type.unwrap(); + + if (!unwrapped.isUDT()) throw new InvalidRequestException(String.format("Invalid user type literal for %s of type %s", receiver.name, receiver.type.asCQL3Type())); - UserType ut = (UserType)receiver.type; + UserType ut = (UserType)unwrapped; for (int i = 0; i < ut.size(); i++) { FieldIdentifier field = ut.fieldName(i); diff --git a/src/java/org/apache/cassandra/cql3/selection/Selectable.java b/src/java/org/apache/cassandra/cql3/selection/Selectable.java index 6e653ba1b9..2218f89407 100644 --- a/src/java/org/apache/cassandra/cql3/selection/Selectable.java +++ b/src/java/org/apache/cassandra/cql3/selection/Selectable.java @@ -529,7 +529,7 @@ public interface Selectable extends AssignmentTestable } Selector.Factory factory = selected.newSelectorFactory(table, expectedUdtType, defs, boundNames); - AbstractType type = factory.getReturnType(); + AbstractType type = factory.getReturnType().unwrap(); if (!type.isUDT()) { throw new InvalidRequestException( diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java index f1b6b8fb87..c6256f7a7a 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java @@ -102,6 +102,22 @@ public class UserTypesTest extends CQLTester ); } + @Test + public void testDescendingOrderingOfUserTypesIsSupported() throws Throwable + { + String myType = createType("CREATE TYPE %s (x double)"); + createTable("CREATE TABLE %s (k int, v frozen<" + myType + ">, b boolean static, PRIMARY KEY (k, v)) WITH CLUSTERING ORDER BY (v DESC)"); + + execute("INSERT INTO %s(k, v) VALUES (?, {x:?})", 1, -104.99251); + execute("UPDATE %s SET b = ? WHERE k = ?", true, 1); + + beforeAndAfterFlush(() -> + assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251), + row(-104.99251) + ) + ); + } + @Test public void testInvalidUDTStatements() throws Throwable {