This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch cassandra-5.0
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/cassandra-5.0 by this push:
     new 7ee239aac9 Unwrap LongType properly when calculating min/max terms in 
V1SSTableIndex
7ee239aac9 is described below

commit 7ee239aac969dcc7bac72fff4e4662fae88ded76
Author: Caleb Rackliffe <[email protected]>
AuthorDate: Tue Sep 1 16:19:24 2026 -0500

    Unwrap LongType properly when calculating min/max terms in V1SSTableIndex
    
    patch by Caleb Rackliffe; reviewed by David Capwell for CASSANDRA-21635
---
 CHANGES.txt                                        |  1 +
 .../index/sai/disk/v1/V1SSTableIndex.java          |  4 +--
 .../cassandra/index/sai/utils/IndexTermType.java   | 10 ------
 .../index/sai/cql/ClusteringKeyIndexTest.java      | 36 ++++++++++++++++++++++
 4 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 335f43572f..800547a91b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 5.0.10
+ * Unwrap LongType properly when calculating min/max terms in V1SSTableIndex 
(CASSANDRA-21635)
  * Force repair should ignore min_repair_interval (CASSANDRA-21552)
  * Render SubnetGroups as JSON in system_views.settings (CASSANDRA-21579)
  * Avoid rebuilding per-SSTable SAI components unless missing or corrupted 
(CASSANDRA-21515)
diff --git 
a/src/java/org/apache/cassandra/index/sai/disk/v1/V1SSTableIndex.java 
b/src/java/org/apache/cassandra/index/sai/disk/v1/V1SSTableIndex.java
index 254d695e40..ef57b29a5a 100644
--- a/src/java/org/apache/cassandra/index/sai/disk/v1/V1SSTableIndex.java
+++ b/src/java/org/apache/cassandra/index/sai/disk/v1/V1SSTableIndex.java
@@ -99,8 +99,8 @@ public class V1SSTableIndex extends SSTableIndex
 
             this.bounds = AbstractBounds.bounds(minKey, true, maxKey, true);
 
-            this.minTerm = metadatas.stream().map(m -> 
m.minTerm).min(indexTermType.comparator()).orElse(null);
-            this.maxTerm = metadatas.stream().map(m -> 
m.maxTerm).max(indexTermType.comparator()).orElse(null);
+            this.minTerm = metadatas.stream().map(m -> 
m.minTerm).reduce(indexTermType::min).orElse(null);
+            this.maxTerm = metadatas.stream().map(m -> 
m.maxTerm).reduce(indexTermType::max).orElse(null);
 
             this.numRows = metadatas.stream().mapToLong(m -> m.numRows).sum();
 
diff --git a/src/java/org/apache/cassandra/index/sai/utils/IndexTermType.java 
b/src/java/org/apache/cassandra/index/sai/utils/IndexTermType.java
index f3c7e2c05f..eeb7cdd1d2 100644
--- a/src/java/org/apache/cassandra/index/sai/utils/IndexTermType.java
+++ b/src/java/org/apache/cassandra/index/sai/utils/IndexTermType.java
@@ -25,7 +25,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
@@ -453,15 +452,6 @@ public class IndexTermType
         }
     }
 
-    public Comparator<ByteBuffer> comparator()
-    {
-        // Override the comparator for BigInteger, frozen collections and 
composite types
-        if (isBigInteger() || isBigDecimal() || isComposite() || isFrozen())
-            return FastByteOperations::compareUnsigned;
-
-        return indexType;
-    }
-
     /**
      * Compare two terms based on their type. This is used in place of {@link 
AbstractType#compare(ByteBuffer, ByteBuffer)}
      * so that the default comparison can be overridden for specific types.
diff --git 
a/test/unit/org/apache/cassandra/index/sai/cql/ClusteringKeyIndexTest.java 
b/test/unit/org/apache/cassandra/index/sai/cql/ClusteringKeyIndexTest.java
index 58443fe0fb..13b0e85e4e 100644
--- a/test/unit/org/apache/cassandra/index/sai/cql/ClusteringKeyIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/sai/cql/ClusteringKeyIndexTest.java
@@ -17,12 +17,15 @@
  */
 package org.apache.cassandra.index.sai.cql;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
 import org.apache.cassandra.index.sai.SAITester;
+import org.apache.cassandra.index.sai.disk.v1.segment.SegmentBuilder;
 
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
 
 public class ClusteringKeyIndexTest extends SAITester
 {
@@ -35,6 +38,12 @@ public class ClusteringKeyIndexTest extends SAITester
         disableCompaction();
     }
 
+    @After
+    public void resetSegmentSize()
+    {
+        SegmentBuilder.updateLastValidSegmentRowId(-1);
+    }
+
     private void insertData1() throws Throwable
     {
         execute("INSERT INTO %s (pk1, pk2, val) VALUES (1, '1', 1)");
@@ -57,6 +66,33 @@ public class ClusteringKeyIndexTest extends SAITester
         runQueries();
     }
 
+
+    @Test
+    public void reversedBigintClusteringMultiSegment()
+    {
+        createTable("CREATE TABLE %s (pk int, ck bigint, PRIMARY KEY (pk, ck)) 
WITH CLUSTERING ORDER BY (ck DESC)");
+        createIndex("CREATE INDEX ON %s(ck) USING 'sai'");
+        disableCompaction(keyspace());
+
+        for (long ck = 10; ck < 16; ck++)
+            execute("INSERT INTO %s (pk, ck) VALUES (?, ?)", 1, ck);
+        flush();
+
+        for (long ck = 16; ck < 22; ck++)
+            execute("INSERT INTO %s (pk, ck) VALUES (?, ?)", 1, ck);
+        flush();
+
+        // Force compaction with a small segment size cap, producing multiple 
segments.
+        SegmentBuilder.updateLastValidSegmentRowId(3);
+        compact();
+
+        for (long ck = 10; ck < 22; ck++)
+        {
+            int cnt = getRows(execute("SELECT ck FROM %s WHERE ck = ?", 
ck)).length;
+            assertEquals("Missing row for ck=" + ck, 1, cnt);
+        }
+    }
+
     private Object[] expectedRow(int index)
     {
         return row(index, Integer.toString(index), index);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to