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

maedhroz 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 4e2e5f3c57 Fixed multiple single-node SAI query bugs relating to 
static columns - Ensure MemtableIndexWriter calculates min/max properly with 
indexes on partition key elements - Ensure only rows with live data are indexed 
- Ensure min cannot be greater than max in intersection statistics with static 
keys - Correct tracking of last key in the searcher in the presence of static 
keys
4e2e5f3c57 is described below

commit 4e2e5f3c57cbd375e1ec112e25578a184618c4b5
Author: Caleb Rackliffe <calebrackli...@gmail.com>
AuthorDate: Thu Feb 20 12:25:07 2025 -0600

    Fixed multiple single-node SAI query bugs relating to static columns
    - Ensure MemtableIndexWriter calculates min/max properly with indexes on 
partition key elements
    - Ensure only rows with live data are indexed
    - Ensure min cannot be greater than max in intersection statistics with 
static keys
    - Correct tracking of last key in the searcher in the presence of static 
keys
    
    patch by Caleb Rackliffe; reviewed by David Capwell for CASSANDRA-20338
---
 CHANGES.txt                                        |  1 +
 .../index/sai/StorageAttachedIndexGroup.java       |  8 +-
 .../index/sai/disk/StorageAttachedIndexWriter.java | 10 ++-
 .../index/sai/disk/v1/MemtableIndexWriter.java     |  6 +-
 .../iterators/KeyRangeIntersectionIterator.java    |  4 +
 .../sai/plan/StorageAttachedIndexSearcher.java     |  4 +-
 .../cassandra/index/sai/utils/PrimaryKey.java      | 18 ++++-
 .../sai/cql/CompositePartitionKeyIndexTest.java    | 88 +++++++++++++++++++++-
 .../index/sai/cql/StaticColumnIndexTest.java       | 44 +++++++++++
 9 files changed, 170 insertions(+), 13 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 4f8ae90366..f4b1be2002 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 5.0.4
+ * Fixed multiple single-node SAI query bugs relating to static columns 
(CASSANDRA-20338)
  * Upgrade com.datastax.cassandra:cassandra-driver-core:3.11.5 to 
org.apache.cassandra:cassandra-driver-core:3.12.1 (CASSANDRA-17231)
  * Update netty to 4.1.119.Final and netty-tcnative to 2.0.70.Final 
(CASSANDRA-20314)
  * Serialization can lose complex deletions in a mutation with multiple 
collections in a row (CASSANDRA-20449)
diff --git 
a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexGroup.java 
b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexGroup.java
index bddeacecc7..02e7971814 100644
--- a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexGroup.java
+++ b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndexGroup.java
@@ -177,7 +177,7 @@ public class StorageAttachedIndexGroup implements 
Index.Group, INotificationCons
             public void insertRow(Row row)
             {
                 // SAI does not index deletions, as these are resolved during 
post-filtering.
-                if (row.deletion().isLive())
+                if (row.hasLiveData(nowInSec, false))
                     for (Index.Indexer indexer : indexers)
                         indexer.insertRow(row);
             }
@@ -185,8 +185,10 @@ public class StorageAttachedIndexGroup implements 
Index.Group, INotificationCons
             @Override
             public void updateRow(Row oldRow, Row newRow)
             {
-                for (Index.Indexer indexer : indexers)
-                    indexer.updateRow(oldRow, newRow);
+                // SAI does not index deletions, as these are resolved during 
post-filtering.
+                if (newRow.hasLiveData(nowInSec, false))
+                    for (Index.Indexer indexer : indexers)
+                        indexer.updateRow(oldRow, newRow);
             }
         };
     }
diff --git 
a/src/java/org/apache/cassandra/index/sai/disk/StorageAttachedIndexWriter.java 
b/src/java/org/apache/cassandra/index/sai/disk/StorageAttachedIndexWriter.java
index f35ae67f93..341bcaac5e 100644
--- 
a/src/java/org/apache/cassandra/index/sai/disk/StorageAttachedIndexWriter.java
+++ 
b/src/java/org/apache/cassandra/index/sai/disk/StorageAttachedIndexWriter.java
@@ -37,6 +37,7 @@ import org.apache.cassandra.index.sai.StorageAttachedIndex;
 import org.apache.cassandra.index.sai.disk.format.IndexDescriptor;
 import org.apache.cassandra.index.sai.utils.PrimaryKey;
 import org.apache.cassandra.io.sstable.SSTableFlushObserver;
+import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.Throwables;
 
 /**
@@ -52,6 +53,8 @@ public class StorageAttachedIndexWriter implements 
SSTableFlushObserver
     private final PerSSTableIndexWriter perSSTableWriter;
     private final Stopwatch stopwatch = Stopwatch.createUnstarted();
     private final RowMapping rowMapping;
+    private final long nowInSeconds = FBUtilities.nowInSeconds();
+
     private DecoratedKey currentKey;
     private boolean tokenOffsetWriterCompleted = false;
     private boolean aborted = false;
@@ -126,9 +129,14 @@ public class StorageAttachedIndexWriter implements 
SSTableFlushObserver
         if (!unfiltered.isRow())
             return;
 
+        // Ignore rows with no live data...
+        Row row = (Row) unfiltered;
+        if (!row.hasLiveData(nowInSeconds, false))
+            return;
+
         try
         {
-            addRow((Row)unfiltered);
+            addRow(row);
         }
         catch (Throwable t)
         {
diff --git 
a/src/java/org/apache/cassandra/index/sai/disk/v1/MemtableIndexWriter.java 
b/src/java/org/apache/cassandra/index/sai/disk/v1/MemtableIndexWriter.java
index 0650e9b9d6..04d3185bfc 100644
--- a/src/java/org/apache/cassandra/index/sai/disk/v1/MemtableIndexWriter.java
+++ b/src/java/org/apache/cassandra/index/sai/disk/v1/MemtableIndexWriter.java
@@ -91,14 +91,16 @@ public class MemtableIndexWriter implements 
PerColumnIndexWriter
         // keys and row IDs in the flushing SSTable. This writer, therefore, 
does nothing in
         // response to the flushing of individual rows except for keeping 
index-specific statistics.
         boolean isStatic = indexTermType.columnMetadata().isStatic();
+        boolean isPartitionKey = 
indexTermType.columnMetadata().isPartitionKey();
 
         // Indexes on static columns should only track static rows, and 
indexes on non-static columns 
         // should only track non-static rows. (Within a partition, the row ID 
for a static row will always
-        // come before any non-static row.) 
-        if (key.kind() == PrimaryKey.Kind.STATIC && isStatic || key.kind() != 
PrimaryKey.Kind.STATIC && !isStatic)
+        // come before any non-static row.) The only exception to this is 
indexes on partition key elements.
+        if ((key.kind() == PrimaryKey.Kind.STATIC && (isStatic || 
isPartitionKey)) || key.kind() != PrimaryKey.Kind.STATIC && !isStatic)
         {
             if (minKey == null)
                 minKey = key;
+
             maxKey = key;
             rowCount++;
             maxSSTableRowId = Math.max(maxSSTableRowId, sstableRowId);
diff --git 
a/src/java/org/apache/cassandra/index/sai/iterators/KeyRangeIntersectionIterator.java
 
b/src/java/org/apache/cassandra/index/sai/iterators/KeyRangeIntersectionIterator.java
index 6237aa0131..4909033bf8 100644
--- 
a/src/java/org/apache/cassandra/index/sai/iterators/KeyRangeIntersectionIterator.java
+++ 
b/src/java/org/apache/cassandra/index/sai/iterators/KeyRangeIntersectionIterator.java
@@ -375,6 +375,10 @@ public class KeyRangeIntersectionIterator extends 
KeyRangeIterator
             min = nullSafeMax(min, range.getMinimum());
             // maximum of the intersection is the smallest maximum of 
individual iterators
             max = nullSafeMin(max, range.getMaximum());
+
+            // With STATIC keys, it is possible for the min to overtake the 
max, which must be corrected. 
+            min = nullSafeMin(min, max);
+
             if (empty)
             {
                 empty = false;
diff --git 
a/src/java/org/apache/cassandra/index/sai/plan/StorageAttachedIndexSearcher.java
 
b/src/java/org/apache/cassandra/index/sai/plan/StorageAttachedIndexSearcher.java
index 858242006a..9116db0d31 100644
--- 
a/src/java/org/apache/cassandra/index/sai/plan/StorageAttachedIndexSearcher.java
+++ 
b/src/java/org/apache/cassandra/index/sai/plan/StorageAttachedIndexSearcher.java
@@ -229,7 +229,7 @@ public class StorageAttachedIndexSearcher implements 
Index.Searcher
                 if (firstKey == null)
                     return Collections.emptyList();
             }
-            while (queryController.doesNotSelect(firstKey) || 
firstKey.equals(lastKey));
+            while (queryController.doesNotSelect(firstKey) || 
firstKey.equals(lastKey, false));
 
             lastKey = firstKey;
             threadLocalNextKeys.add(firstKey);
@@ -291,7 +291,7 @@ public class StorageAttachedIndexSearcher implements 
Index.Searcher
                 if (key == null)
                     break;
 
-                if (queryController.doesNotSelect(key) || key.equals(lastKey))
+                if (queryController.doesNotSelect(key) || key.equals(lastKey, 
false))
                     continue;
 
                 nextPrimaryKeys.add(key);
diff --git a/src/java/org/apache/cassandra/index/sai/utils/PrimaryKey.java 
b/src/java/org/apache/cassandra/index/sai/utils/PrimaryKey.java
index 3cc5033044..6de7a6c884 100644
--- a/src/java/org/apache/cassandra/index/sai/utils/PrimaryKey.java
+++ b/src/java/org/apache/cassandra/index/sai/utils/PrimaryKey.java
@@ -218,10 +218,20 @@ public interface PrimaryKey extends 
Comparable<PrimaryKey>, ByteComparable
             }
 
             @Override
-            public boolean equals(Object obj)
+            public boolean equals(Object o)
             {
-                if (obj instanceof PrimaryKey)
-                    return compareTo((PrimaryKey) obj) == 0;
+                if (o instanceof PrimaryKey)
+                    return compareTo((PrimaryKey) o) == 0;
+                return false;
+            }
+
+            @Override
+            public boolean equals(Object o, boolean strict)
+            {
+                if (o == null)
+                    return false;
+                if (o instanceof PrimaryKey)
+                    return compareTo((PrimaryKey) o, strict) == 0;
                 return false;
             }
 
@@ -494,4 +504,6 @@ public interface PrimaryKey extends Comparable<PrimaryKey>, 
ByteComparable
     {
         return compareTo(key);
     }
+
+    boolean equals(Object obj, boolean strict);
 }
diff --git 
a/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
 
b/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
index 5d3c9e11d7..d7aa4e48ab 100644
--- 
a/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
+++ 
b/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
@@ -22,19 +22,99 @@ import java.math.BigInteger;
 import org.junit.Test;
 
 import org.apache.cassandra.cql3.restrictions.StatementRestrictions;
+import org.apache.cassandra.db.marshal.ByteType;
 import org.apache.cassandra.db.marshal.FloatType;
+import org.apache.cassandra.db.marshal.IntegerType;
 import org.apache.cassandra.db.marshal.SimpleDateType;
 import org.apache.cassandra.db.marshal.TimeType;
 import org.apache.cassandra.db.marshal.UUIDType;
 import org.apache.cassandra.index.sai.SAITester;
+import org.apache.cassandra.utils.ByteBufferUtil;
 
 public class CompositePartitionKeyIndexTest extends SAITester
 {
+    @Test
+    public void testStaticAndNonStaticKeysOnFlush() throws Throwable
+    {
+        createTable("CREATE TABLE %s (pk0 tinyint, pk1 bigint, ck0 blob, s1 
text static, s0 set<uuid> static, v0 smallint, PRIMARY KEY ((pk0, pk1), ck0)) 
WITH CLUSTERING ORDER BY (ck0 DESC)");
+        disableCompaction(KEYSPACE);
+        createIndex("CREATE INDEX tbl_pk0 ON %s(pk0) USING 'sai'");
+        createIndex("CREATE INDEX tbl_pk1 ON %s(pk1) USING 'sai'");
+        createIndex("CREATE INDEX tbl_s1 ON %s(s1) USING 'sai'");
+        createIndex("CREATE INDEX tbl_v0 ON %s(v0) USING  'sai'");
+
+        execute("INSERT INTO %s (pk0, pk1, ck0, s1, s0, v0) VALUES (-62, 
-5815950741950477880, 0x326f, '켅\uF6EB憓ᤃ\uEF32ꝃ窰ŷ', 
{00000000-0000-4700-aa00-000000000000}, 19310) USING TIMESTAMP 1");
+        execute("DELETE FROM %s USING TIMESTAMP 2 WHERE  pk0 = 45 AND  pk1 = 
6014418364385708772 AND  ck0 = 0x7c10");
+        execute("DELETE FROM %s USING TIMESTAMP 3 WHERE  pk0 = -41 AND  pk1 = 
-3934225888295599640");
+        execute("INSERT INTO %s (pk0, pk1, ck0, s1, s0, v0) " +
+                "VALUES (-64, 7973592261481566341, 0x0d, '\uE11B摻', 
{00000000-0000-4800-8900-000000000000, 00000000-0000-4900-8600-000000000000}, 
-23873) USING TIMESTAMP 4");
+        flush(KEYSPACE);
+
+        execute("UPDATE %s USING TIMESTAMP 5 SET v0=-359, s1='ل≻Ⱆ喡䮠?' WHERE  
pk0 = -64 AND  pk1 = 7973592261481566341 AND  ck0 = 0x99d570024de738f37877");
+        execute("INSERT INTO %s (pk0, pk1, ck0, v0, s1, s0) " +
+                "VALUES (-104, -4990846884898776392, 0xf7ac771298eaf1d4, 
-6977, '凘纖볭菮⏏↶?蜑', null) USING TIMESTAMP 6");
+        execute("INSERT INTO %s (pk0, pk1, ck0, s1, s0, v0) " +
+                "VALUES (-62, -5815950741950477880, 0x9277e744212e1c4b50, 
'\uF6AD瀛⛕徳倬糽ᢷ' + '雴', {00000000-0000-4700-b100-000000000000, 
00000000-0000-4800-9300-000000000000}, 5423) USING TIMESTAMP 7");
+        execute("DELETE FROM %s USING TIMESTAMP 8 WHERE  pk0 = -64 AND  pk1 = 
7973592261481566341");
+        flush(KEYSPACE);
+
+        execute("DELETE s0, s1, s0 FROM %s USING TIMESTAMP 9 WHERE  pk0 = -62 
AND  pk1 = -5815950741950477880");
+        execute("DELETE FROM %s USING TIMESTAMP 10 WHERE  pk0 = -41 AND  pk1 = 
-3934225888295599640 AND  ck0 = 0xd753dc3a473acaf665");
+        execute("INSERT INTO %s (pk0, pk1, ck0, s1, s0, v0) " +
+                "VALUES (-62, -5815950741950477880, 0xd1e07b568a7188, 'ᑿ鼾戆' + 
'篐뵡?䰫', {00000000-0000-4500-b000-000000000000}, 17933) USING TIMESTAMP 11");
+        execute("UPDATE %s USING TIMESTAMP 12 SET v0=null, 
s0={00000000-0000-4600-a000-000000000000, 00000000-0000-4d00-8200-000000000000, 
00000000-0000-4f00-9200-000000000000} " +
+                "WHERE  pk0 = -41 AND  pk1 = -3934225888295599640 AND  ck0 = 
0x0dab3b038131efa2");
+
+        assertRowCount(execute("SELECT * FROM %s WHERE pk0 >= ? LIMIT 81", 
(byte) -104), 5);
+        execute("DELETE FROM %s USING TIMESTAMP 13 WHERE  pk0 = -64 AND  pk1 = 
7973592261481566341");
+        flush(KEYSPACE);
+
+        beforeAndAfterFlush(() ->
+                            assertRows(execute("SELECT pk0, pk1, ck0 FROM %s 
WHERE pk0 >= ?", (byte) -104),
+                                       row((byte) -62, -5815950741950477880L, 
ByteBufferUtil.hexToBytes("d1e07b568a7188")),
+                                       row((byte) -62, -5815950741950477880L, 
ByteBufferUtil.hexToBytes("9277e744212e1c4b50")),
+                                       row((byte) -62, -5815950741950477880L, 
ByteBufferUtil.hexToBytes("326f")),
+                                       row((byte) -104, -4990846884898776392L, 
ByteBufferUtil.hexToBytes("f7ac771298eaf1d4")),
+                                       row((byte) -41, -3934225888295599640L, 
null)));
+    }
+
+    @Test
+    public void testIgnoreCellDeletions() throws Throwable
+    {
+        createTable("CREATE TABLE %s (pk0 boolean, pk1 varint, ck0 tinyint, 
ck1 varint, s0 list<frozen<map<double, smallint>>> static, " +
+                    "                 s1 map<frozen<set<uuid>>, 
frozen<map<inet, date>>> static, v0 frozen<map<frozen<set<text>>, uuid>>, " +
+                    "                 PRIMARY KEY ((pk0, pk1), ck0, ck1)) WITH 
CLUSTERING ORDER BY (ck0 DESC, ck1 DESC)");
+        disableCompaction(KEYSPACE);
+        createIndex("CREATE INDEX tbl_pk0 ON %s(pk0) USING 'sai'");
+
+        execute("INSERT INTO %s (pk0, pk1, ck0, ck1, s0, s1, v0) " +
+                "VALUES (true, 0, 109, 0, [{2.2352903520430565E260: -29214, 
2.605618737869944E274: -13041}], " +
+                "        {{00000000-0000-4400-9f00-000000000000, 
00000000-0000-4500-9b00-000000000000, 00000000-0000-4b00-bf00-000000000000}: 
{'18.112.79.221': '-2306623-03-19', '227.58.183.116': '-3929454-04-25'}}, " +
+                "        {{'⭎憢?', '黣偛紑'}: 
00000000-0000-4900-8600-000000000000, {'㛽ꓗ', '剢ꮱ死䰀륬ਐ喑ퟚ', '竖䝏爐뷤曀'}: 
00000000-0000-4900-bc00-000000000000}) USING TIMESTAMP 1");
+        execute("INSERT INTO %s (pk0, pk1, ck0, ck1, s1, v0) " +
+                "VALUES (true, 0, 114, 742, 
{{00000000-0000-4000-9a00-000000000000, 00000000-0000-4700-ba00-000000000000}: 
{'96.31.70.25': '-912836-06-15', '185.90.18.173': '-5257542-01-31', 
'223.18.191.245': '-4633145-10-30'}}, " +
+                "                           {{'뫥㩎뎠ྭẒ'}: 
00000000-0000-4800-8600-000000000000}) USING TIMESTAMP 2");
+
+        // This will result in the creation of erroneous postings if cell 
deletions are not accounted for:
+        execute("DELETE v0, s1, s0 FROM %s USING TIMESTAMP 6 WHERE  pk0 = true 
AND  pk1 = 0 AND  ck0 = 121 AND  ck1 = 1");
+
+        execute("UPDATE %s USING TIMESTAMP 8 SET s0 += 
[{4.3056056376102396E-169: 22551, 1.439623561042819E208: 20450}, 
{-2.7900719406964408E-242: 30147, 8.586565205109037E-211: 28721, 
4.603864140847754E20: -12814}], " +
+                "                                s1 += 
{{00000000-0000-4200-b900-000000000000, 00000000-0000-4500-ab00-000000000000}: 
{'2.67.240.121': '-471656-04-17', '134.186.187.51': '-2056459-04-13'}}, " +
+                "                                v0={{'?', '蠥╩徰昰弳펠재', 
'됢簔Ὕ텇⢌យ稭澣'}: 00000000-0000-4d00-8d00-000000000000} " +
+                "WHERE  pk0 = true AND  pk1 = 0 AND  ck0 = 37 AND  ck1 = 0");
+
+        beforeAndAfterFlush(() ->
+                assertRows(execute("SELECT pk0, pk1, ck0, ck1 FROM %s WHERE 
pk0 = ? LIMIT 4", true),
+                           row(true, IntegerType.instance.fromString("0"), 
ByteType.instance.fromString("114"), IntegerType.instance.fromString("742")),
+                           row(true, IntegerType.instance.fromString("0"), 
ByteType.instance.fromString("109"), IntegerType.instance.fromString("0")),
+                           row(true, IntegerType.instance.fromString("0"), 
ByteType.instance.fromString("37"), IntegerType.instance.fromString("0"))));
+    }
+
     @Test
     public void testIntersectionOnMixedPostingsOnDelete() throws Throwable
     {
         createTable("CREATE TABLE %s (pk0 boolean, pk1 uuid, ck0 date, ck1 
smallint, s0 timeuuid static, v0 bigint, v1 float, PRIMARY KEY ((pk0, pk1), 
ck0, ck1)) WITH CLUSTERING ORDER BY (ck0 DESC, ck1 ASC)");
-
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX tbl_pk0 ON %s(pk0) USING 'sai'");
         createIndex("CREATE INDEX tbl_ck0 ON %s(ck0) USING 'sai'");
 
@@ -54,7 +134,7 @@ public class CompositePartitionKeyIndexTest extends SAITester
     public void testIntersectionOnMixedPostingsOnUpdate() throws Throwable
     {
         createTable("CREATE TABLE %s (pk0 boolean, pk1 uuid, ck0 date, ck1 
smallint, s0 timeuuid static, v0 bigint, v1 float, PRIMARY KEY ((pk0, pk1), 
ck0, ck1)) WITH CLUSTERING ORDER BY (ck0 DESC, ck1 ASC)");
-
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX tbl_pk0 ON %s(pk0) USING 'sai'");
         createIndex("CREATE INDEX tbl_ck0 ON %s(ck0) USING 'sai'");
 
@@ -74,6 +154,7 @@ public class CompositePartitionKeyIndexTest extends SAITester
     public void testIntersectionWithStaticOverlap() throws Throwable
     {
         createTable("CREATE TABLE %s (pk0 int, pk1 int, ck0 int, s1 int 
static, v0 int, PRIMARY KEY((pk0, pk1), ck0))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX ON %s(pk0) USING 'sai'");
 
         execute("UPDATE %s USING TIMESTAMP 1 SET s1 = 0, v0 = 0 WHERE pk0 = 0 
AND pk1 = 1 AND ck0 = 0");
@@ -91,6 +172,7 @@ public class CompositePartitionKeyIndexTest extends SAITester
     public void testIntersectionWithStaticUpdate() throws Throwable
     {
         createTable("CREATE TABLE %s (pk0 time, pk1 varint, ck0 date, s0 
boolean static, s1 text static, v0 boolean, PRIMARY KEY ((pk0, pk1), ck0))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX tbl_pk0 ON %s(pk0) USING 'sai'");
         createIndex("CREATE INDEX tbl_s0 ON %s(s0) USING 'sai'");
 
@@ -116,6 +198,7 @@ public class CompositePartitionKeyIndexTest extends 
SAITester
     public void testCompositePartitionIndex() throws Throwable
     {
         createTable("CREATE TABLE %s (pk1 int, pk2 text, val int, PRIMARY 
KEY((pk1, pk2)))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX ON %s(pk1) USING 'sai'");
         createIndex("CREATE INDEX ON %s(pk2) USING 'sai'");
 
@@ -168,6 +251,7 @@ public class CompositePartitionKeyIndexTest extends 
SAITester
     public void testFilterWithIndexForContains() throws Throwable
     {
         createTable("CREATE TABLE %s (k1 int, k2 int, v set<int>, PRIMARY KEY 
((k1, k2)))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX ON %s(k2) USING 'sai'");
 
         execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 0, 0, set(1, 2, 
3));
diff --git 
a/test/unit/org/apache/cassandra/index/sai/cql/StaticColumnIndexTest.java 
b/test/unit/org/apache/cassandra/index/sai/cql/StaticColumnIndexTest.java
index faaf74f5c6..d9dec8e3a7 100644
--- a/test/unit/org/apache/cassandra/index/sai/cql/StaticColumnIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/sai/cql/StaticColumnIndexTest.java
@@ -20,6 +20,9 @@ package org.apache.cassandra.index.sai.cql;
 
 import org.junit.Test;
 
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.TimeType;
+import org.apache.cassandra.db.marshal.UUIDType;
 import org.apache.cassandra.index.sai.SAITester;
 
 public class StaticColumnIndexTest extends SAITester
@@ -28,6 +31,7 @@ public class StaticColumnIndexTest extends SAITester
     public void staticIndexReturnsAllRowsInPartition() throws Throwable
     {
         createTable("CREATE TABLE %s (pk int, ck int, val1 int static, val2 
int, PRIMARY KEY(pk, ck))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX ON %s(val1) USING 'sai'");
 
         execute("INSERT INTO %s(pk, ck, val1, val2) VALUES(?, ?, ?, ?)", 1, 1, 
2, 1);
@@ -42,6 +46,7 @@ public class StaticColumnIndexTest extends SAITester
     public void staticIndexAndNonStaticIndex() throws Throwable
     {
         createTable("CREATE TABLE %s (pk int, ck int, val1 int static, val2 
int, PRIMARY KEY(pk, ck))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX ON %s(val1) USING 'sai'");
         createIndex("CREATE INDEX ON %s(val2) USING 'sai'");
 
@@ -57,6 +62,7 @@ public class StaticColumnIndexTest extends SAITester
     public void staticAndNonStaticRangeIntersection() throws Throwable
     {
         createTable("CREATE TABLE %s (pk int, ck int, v1 int, s1 int static, 
PRIMARY KEY(pk, ck))");
+        disableCompaction(KEYSPACE);
         createIndex("CREATE INDEX ON %s(v1) USING 'sai'");
         createIndex("CREATE INDEX ON %s(s1) USING 'sai'");
 
@@ -71,4 +77,42 @@ public class StaticColumnIndexTest extends SAITester
 
         beforeAndAfterFlush(() -> assertRowCount(execute("SELECT * FROM %s 
WHERE pk = ? AND v1 > ? AND s1 = ?", 0, 2, 100), 3));
     }
+
+    @Test
+    public void testTupleAndBlobFiltering() throws Throwable
+    {
+        String blobTupleType = createType("CREATE TYPE IF NOT EXISTS %s (f0 
blob)");
+        String boolTinyTextType = createType("CREATE TYPE IF NOT EXISTS %s (f0 
boolean, f1 tinyint, f2 text)");
+        createTable("CREATE TABLE %s (pk0 time, pk1 uuid, ck0 uuid, ck1 blob, 
s0 frozen<tuple<smallint, frozen<set<float>>>> static, " +
+                    "                 v0 vector<vector<int, 2>, 3>, v1 
frozen<map<frozen<" + blobTupleType + ">, vector<bigint, 2>>>, " +
+                    "                 v2 vector<frozen<" + boolTinyTextType + 
">, 2>, v3 bigint, PRIMARY KEY ((pk0, pk1), ck0, ck1)) WITH CLUSTERING ORDER BY 
(ck0 DESC, ck1 DESC)");
+        disableCompaction(KEYSPACE);
+        createIndex("CREATE INDEX tbl_pk1 ON %s(pk1) USING 'sai'");
+        createIndex("CREATE INDEX tbl_s0 ON %s(s0) USING 'sai'");
+
+        execute("INSERT INTO %s (pk0, pk1, ck0, ck1, s0, v0, v1, v2, v3) " +
+                "VALUES ('02:43:47.716011275', 
00000000-0000-4200-b200-000000000000, 00000000-0000-4e00-8400-000000000000, 
0xf2791941aea8e469, " +
+                "        (12129, {-2.58545975E14}), [[-1781797567, 330686172], 
[103364202, 2031130152], [-550709009, 492544493]], " +
+                "        {{f0: 0x34839b8bae653b2bdee8}: [-8431172225521461427, 
8894719445990427242]}, [{f0: false, f1: 53, f2: '嵆왛孷쏆䊖恣'}, {f0: true, f1: 21, 
f2: 'ᨚ?榥쯢?ɚ챛ퟡ'}], 9167463065336786821) USING TIMESTAMP 3");
+        execute("UPDATE %s USING TIMESTAMP 4 " +
+                "SET s0=(23307, {-8.214548E-18}), v0=[[672139924, 
-1253475201], [353181149, -1829076723], [179355765, 379303855]], " +
+                "    v1={{f0: 0x64850696464d}: [-7485547085069825418, 
7795885370802556756], {f0: 0x67633db6f091}: [-8484578637223040646, 
8216210044102487771]}, " +
+                "    v2=[{f0: true, f1: 68, f2: '䝿ᝧ䶨푥펟겭매郂쀌'}, {f0: true, f1: 
98, f2: '髃爫삿챥卛☓읂ີ?'}], v3=-4626482462417652499 * -7377486305688263453 " +
+                "WHERE  pk0 = '03:36:30.876439626' AND  pk1 = 
00000000-0000-4000-ad00-000000000000 AND  ck0 = 
00000000-0000-4000-9f00-000000000000 AND  ck1 = 0xa06bb301");
+        execute("INSERT INTO %s (pk0, pk1, ck0, ck1, s0, v0, v1, v2, v3) " +
+                "VALUES ('07:08:47.775161332', 
00000000-0000-4800-ad00-000000000000, 00000000-0000-4a00-a500-000000000000, 
0xfef0d63ff7, (-15283, {-1.132058E24, 2.9319742E-31}), " +
+                "        [[-335960956, 678086816], [-2139882146, 1011627708], 
[-55338955, -2094185756]], {{f0: 0xd9c3ab}: [-9002034104664383537, 
-8074261670215737032]}, " +
+                "        [{f0: true, f1: -79, f2: '霠♘칳⦵ঋ幗䶐'}, {f0: true, f1: 
7, f2: '䉻ݹ鞞텔㙠'}], 1885613374025825905) USING TIMESTAMP 5");
+        execute("DELETE FROM %s USING TIMESTAMP 6 WHERE  pk0 = 
'14:02:14.975449434' AND  pk1 = 00000000-0000-4900-9900-000000000000");
+        execute("DELETE FROM %s USING TIMESTAMP 7 WHERE  pk0 = 
'12:15:35.151327231' AND  pk1 = 00000000-0000-4500-ac00-000000000000");
+        execute("DELETE FROM %s USING TIMESTAMP 8 WHERE  pk0 = 
'07:08:47.775161332' AND  pk1 = 00000000-0000-4800-ad00-000000000000 AND  ck0 = 
00000000-0000-4b00-b000-000000000000 AND  ck1 = 0xa4121adb08");
+        execute("INSERT INTO %s (pk0, pk1, ck0, ck1, s0, v0, v1, v2, v3) " +
+                "VALUES ('03:36:30.876439626', 
00000000-0000-4000-ad00-000000000000, 00000000-0000-4600-b400-000000000000, 
0x63f5, (28387, {-1.18764904E-20}), " +
+                "        [[-441895935, 313114446], [-740629531, -678512740], 
[1429899934, -1259907921]], {{f0: 0x5df1}: [414225888834712632, 
-5730196176171247108], " +
+                "        {f0: 0x92c1497d7072b81c91}: [-7587541014989351350, 
-2813091340484612608]}, [{f0: true, f1: 41, f2: '쎺╇⒀왶'}, {f0: true, f1: -84, 
f2: '턺䋏篷'}], -1473884563651667176 + 128345915915881356) USING TIMESTAMP 9");
+
+        beforeAndAfterFlush(() -> assertRows(execute("SELECT pk0, pk1, ck0, 
ck1 FROM %s WHERE s0 = (28387, {-1.18764904E-20}) AND pk1 = 
00000000-0000-4000-ad00-000000000000 AND ck1 = 0xa06bb301 LIMIT 307 ALLOW 
FILTERING"),
+                                             
row(TimeType.instance.fromString("03:36:30.876439626"), 
UUIDType.instance.fromString("00000000-0000-4000-ad00-000000000000"), 
+                                                 
UUIDType.instance.fromString("00000000-0000-4000-9f00-000000000000"), 
BytesType.instance.fromString("a06bb301"))));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to