From 1e8a1a21abb5ba93cf1d5aae1c7394546f9f90ac Mon Sep 17 00:00:00 2001 From: Ekaterina Dimitrova Date: Mon, 8 Jan 2024 10:09:49 -0500 Subject: [PATCH] Fix data corruption in VectorCodec when using heap buffers patch by Ekaterina Dimitrova, reviewed by Andres de la Pena for CASSANDRA-19168 --- CHANGES.txt | 1 + .../cql3/functions/types/VectorCodec.java | 16 +++++++++------- .../validation/operations/CQLVectorTest.java | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 90cb544d10..409a8c4f5b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.0-beta2 + * Fix data corruption in VectorCodec when using heap buffers (CASSANDRA-19167) * Avoid over-skipping of key iterators from static column indexes during mixed intersections (CASSANDRA-19278) * Make concurrent_index_builders configurable at runtime (CASSANDRA-19266) * Fix storage_compatibility_mode for streaming (CASSANDRA-19126) diff --git a/src/java/org/apache/cassandra/cql3/functions/types/VectorCodec.java b/src/java/org/apache/cassandra/cql3/functions/types/VectorCodec.java index c54b8da7b8..3507ae3778 100644 --- a/src/java/org/apache/cassandra/cql3/functions/types/VectorCodec.java +++ b/src/java/org/apache/cassandra/cql3/functions/types/VectorCodec.java @@ -127,18 +127,20 @@ public abstract class VectorCodec extends TypeCodec> : String.format("Expected elements of uniform size, observed %d elements with total bytes %d", type.getDimensions(), bytes.remaining()); + ByteBuffer bb = bytes.slice(); ImmutableList.Builder values = ImmutableList.builder(); for (int i = 0; i < type.getDimensions(); ++i) { - ByteBuffer slice = bytes.slice(); - slice.limit(elementSize); - values.add(subtypeCodec.deserialize(slice, protocolVersion)); - bytes.position(bytes.position() + elementSize); + int originalPosition = bb.position(); + // Set the limit for the current element + bb.limit(originalPosition + elementSize); + values.add(subtypeCodec.deserialize(bb, protocolVersion)); + // Move to the start of the next element + bb.position(originalPosition + elementSize); + // Reset the limit to the end of the buffer + bb.limit(bb.capacity()); } - // Restore the input ByteBuffer to its original state - bytes.rewind(); - return values.build(); } } diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/CQLVectorTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/CQLVectorTest.java index 3b361bd29c..2a0d665bbe 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/CQLVectorTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/CQLVectorTest.java @@ -404,7 +404,7 @@ public class CQLVectorTest extends CQLTester.InMemory Vector vector = vector(1, 2); execute("INSERT INTO %s (pk, value) VALUES (0, ?)", vector); - // identitiy function + // identity function String f = createFunction(KEYSPACE, "", "CREATE FUNCTION %s (x vector) " +