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

maedhroz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit ef0eec07f810c2d2d53fb9649a2df827a97bd033
Merge: d06e496773 4e2e5f3c57
Author: Caleb Rackliffe <calebrackli...@gmail.com>
AuthorDate: Tue Apr 8 22:07:06 2025 -0500

    Merge branch 'cassandra-5.0' into trunk
    
    * cassandra-5.0:
      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

 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 +++-
 .../test/log/BounceIndexRebuildTest.java           | 10 ++-
 .../sai/cql/CompositePartitionKeyIndexTest.java    | 99 +++++++++++++++++++++-
 .../index/sai/cql/StaticColumnIndexTest.java       | 48 +++++++++++
 10 files changed, 192 insertions(+), 16 deletions(-)

diff --cc CHANGES.txt
index 4b9488ff1e,f4b1be2002..6c627f596a
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,176 -1,5 +1,177 @@@
 -5.0.4
 +5.1
 + * Add SSTableIntervalTree latency metric (CASSANDRA-20502)
 + * Ignore repetitions of semicolon in CQLSH (CASSANDRA-19956)
 + * Avoid NPE during cms initialization abort (CASSANDRA-20527)
 + * Avoid failing queries when epoch changes and replica goes up/down 
(CASSANDRA-20489)
 + * Split out truncation record lock (CASSANDRA-20480)
 + * Throw new IndexBuildInProgressException when queries fail during index 
build, instead of IndexNotAvailableException (CASSANDRA-20402)
 + * Fix Paxos repair interrupts running transactions (CASSANDRA-20469)
 + * Various fixes in constraint framework (CASSANDRA-20481)
 + * Add support in CAS for -= on numeric types, and fixed improper handling of 
empty bytes which lead to NPE (CASSANDRA-20477)
 + * Do not fail to start a node with materialized views after they are turned 
off in config (CASSANDRA-20452)
 + * Fix nodetool gcstats output, support human-readable units and more output 
formats (CASSANDRA-19022)
 + * Various gossip to TCM upgrade fixes (CASSANDRA-20483)
 + * Add nodetool command to abort failed nodetool cms initialize 
(CASSANDRA-20482)
 + * Repair Paxos for the distributed metadata log when CMS membership changes 
(CASSANDRA-20467)
 + * Reintroduce CASSANDRA-17411 in trunk (CASSANDRA-19346)
 + * Add min/max/mean/percentiles to timer metrics vtable (CASSANDRA-20466)
 + * Add support for time, date, timestamp types in scalar constraint 
(CASSANDRA-20274)
 + * Add regular expression constraint (CASSANDRA-20275)
 + * Improve constraints autocompletion (CASSANDRA-20341)
 + * Add JVM version and Cassandra build date to nodetool version -v 
(CASSANDRA-19721)
 + * Move all disk error logic to DiskErrorsHandler to enable pluggability 
(CASSANDRA-20363)
 + * Fix marking an SSTable as suspected and BufferPool leakage in case of a 
corrupted SSTable read during a compaction (CASSANDRA-20396)
 + * Add missed documentation for CREATE TABLE LIKE (CASSANDRA-20401)
 + * Add OCTET_LENGTH constraint (CASSANDRA-20340)
 + * Reduce memory allocations in miscellaneous places along the hot write path 
(CASSANDRA-20167)
 + * Provide keystore_password_file and truststore_password_file options to 
read credentials from a file (CASSANDRA-13428)
 + * Unregistering a node should also remove it from tokenMap if it is there 
and recalculate the placements (CASSANDRA-20346)
 + * Fix PartitionUpdate.isEmpty deserialization issue to avoid potential 
EOFException (CASSANDRA-20345)
 + * Avoid adding LEFT nodes to tokenMap on upgrade from gossip 
(CASSANDRA-20344)
 + * Allow empty placements when deserializing cluster metadata 
(CASSANDRA-20343)
 + * Reduce heap pressure when initializing CMS (CASSANDRA-20267)
 + * Paxos Repair: NoSuchElementException on 
DistributedSchema.getKeyspaceMetadata (CASSANDRA-20320)
 + * Improve performance of DistributedSchema.validate for large schemas 
(CASSANDRA-20360)
 + * Add JSON constraint (CASSANDRA-20273)
 + * Prevent invalid constraint combinations (CASSANDRA-20330)
 + * Support CREATE TABLE LIKE WITH INDEXES (CASSANDRA-19965)
 + * Invalidate relevant prepared statements on every change to TableMetadata 
(CASSANDRA-20318)
 + * Add per type max size guardrails (CASSANDRA-19677)
 + * Make it possible to abort all kinds of multi step operations 
(CASSANDRA-20217)
 + * Do not leak non-Java exceptions when calling snapshot operations via JMX 
(CASSANDRA-20335)
 + * Implement NOT_NULL constraint (CASSANDRA-20276)
 + * Improve error messages for constraints (CASSANDRA-20266)
 + * Add system_views.partition_key_statistics for querying SSTable metadata 
(CASSANDRA-20161)
 + * CEP-42 - Add Constraints Framework (CASSANDRA-19947)
 + * Add table metric PurgeableTombstoneScannedHistogram and a tracing event 
for scanned purgeable tombstones (CASSANDRA-20132)
 + * Make sure we can parse the expanded CQL before writing it to the log or 
sending it to replicas (CASSANDRA-20218)
 + * Add format_bytes and format_time functions (CASSANDRA-19546)
 + * Fix error when trying to assign a tuple to target type not being a tuple 
(CASSANDRA-20237)
 + * Fail CREATE TABLE LIKE statement if UDTs in target keyspace do not exist 
or they have different structure from ones in source keyspace (CASSANDRA-19966)
 + * Support octet_length and length functions (CASSANDRA-20102)
 + * Make JsonUtils serialize Instant always with the same format 
(CASSANDRA-20209)
 + * Port Harry v2 to trunk (CASSANDRA-20200)
 + * Enable filtering of snapshots on keyspace, table and snapshot name in 
nodetool listsnapshots (CASSANDRA-20151)
 + * Create manifest upon loading where it does not exist or enrich it 
(CASSANDRA-20150)
 + * Propagate true size of snapshot in SnapshotDetailsTabularData to not call 
JMX twice in nodetool listsnapshots (CASSANDRA-20149)
 + * Implementation of CEP-43 - copying a table via CQL by CREATE TABLE LIKE 
(CASSANDRA-19964)
 + * Periodically disconnect roles that are revoked or have LOGIN=FALSE set 
(CASSANDRA-19385)
 + * AST library for CQL-based fuzz tests (CASSANDRA-20198)
 + * Support audit logging for JMX operations (CASSANDRA-20128)
 + * Enable sorting of nodetool status output (CASSANDRA-20104)
 + * Support downgrading after CMS is initialized (CASSANDRA-20145)
 + * Deprecate IEndpointSnitch (CASSANDRA-19488)
 + * Check presence of a snapshot in a case-insensitive manner on macOS 
platform to prevent hardlinking failures (CASSANDRA-20146)
 + * Enable JMX server configuration to be in cassandra.yaml (CASSANDRA-11695)
 + * Parallelized UCS compactions (CASSANDRA-18802)
 + * Avoid prepared statement invalidation race when committing schema changes 
(CASSANDRA-20116)
 + * Restore optimization in MultiCBuilder around building one clustering 
(CASSANDRA-20129)
 + * Consolidate all snapshot management to SnapshotManager and introduce 
SnapshotManagerMBean (CASSANDRA-18111)
 + * Fix RequestFailureReason constants codes (CASSANDRA-20126)
 + * Introduce SSTableSimpleScanner for compaction (CASSANDRA-20092)
 + * Include column drop timestamp in alter table transformation 
(CASSANDRA-18961)
 + * Make JMX SSL configurable in cassandra.yaml (CASSANDRA-18508)
 + * Fix cqlsh CAPTURE command to save query results without trace details when 
TRACING is ON (CASSANDRA-19105)
 + * Optionally prevent tombstone purging during repair (CASSANDRA-20071)
 + * Add post-filtering support for the IN operator in SAI queries 
(CASSANDRA-20025)
 + * Don’t finish ongoing decommission and move operations during startup 
(CASSANDRA-20040)
 + * Nodetool reconfigure cms has correct return code when streaming fails 
(CASSANDRA-19972)
 + * Reintroduce RestrictionSet#iterator() optimization around multi-column 
restrictions (CASSANDRA-20034)
 + * Explicitly localize strings to Locale.US for internal implementation 
(CASSANDRA-19953)
 + * Add -H option for human-friendly output in nodetool compactionhistory 
(CASSANDRA-20015)
 + * Fix type check for referenced duration type for nested types 
(CASSANDRA-19890)
 + * In simulation tests, correctly set the tokens of replacement nodes 
(CASSANDRA-19997)
 + * During TCM upgrade, retain all properties of existing system tables 
(CASSANDRA-19992)
 + * Properly cancel in-flight futures and reject requests in 
EpochAwareDebounce during shutdown (CASSANDRA-19848)
 + * Provide clearer exception message on failing commitlog_disk_access_mode 
combinations (CASSANDRA-19812)
 + * Add total space used for a keyspace to nodetool tablestats 
(CASSANDRA-19671)
 + * Ensure Relation#toRestriction() handles ReversedType properly 
(CASSANDRA-19950)
 + * Add JSON and YAML output option to nodetool gcstats (CASSANDRA-19771)
 + * Introduce metadata serialization version V4 (CASSANDRA-19970)
 + * Allow CMS reconfiguration to work around DOWN nodes (CASSANDRA-19943)
 + * Make TableParams.Serializer set allowAutoSnapshots and incrementalBackups 
(CASSANDRA-19954)
 + * Make sstabledump possible to show tombstones only (CASSANDRA-19939)
 + * Ensure that RFP queries potentially stale replicas even with only key 
columns in the row filter (CASSANDRA-19938)
 + * Allow nodes to change IP address while upgrading to TCM (CASSANDRA-19921)
 + * Retain existing keyspace params on system tables after upgrade 
(CASSANDRA-19916)
 + * Deprecate use of gossip state for paxos electorate verification 
(CASSANDRA-19904)
 + * Update dtest-api to 0.0.17 to fix jvm17 crash in jvm-dtests 
(CASSANDRA-19239)
 + * Add resource leak test and Update Netty to 4.1.113.Final to fix leak 
(CASSANDRA-19783)
 + * Fix incorrect nodetool suggestion when gossip mode is running 
(CASSANDRA-19905)
 + * SAI support for BETWEEN operator (CASSANDRA-19688)
 + * Fix BETWEEN filtering for reversed clustering columns (CASSANDRA-19878)
 + * Retry if node leaves CMS while committing a transformation 
(CASSANDRA-19872)
 + * Add support for NOT operators in WHERE clauses. Fixed Three Valued Logic 
(CASSANDRA-18584)
 + * Allow getendpoints for system tables and make sure getNaturalReplicas work 
for MetaStrategy (CASSANDRA-19846)
 + * On upgrade, handle pre-existing tables with unexpected table ids 
(CASSANDRA-19845)
 + * Reconfigure CMS before assassinate (CASSANDRA-19768)
 + * Warn about unqualified prepared statement only if it is select or 
modification statement (CASSANDRA-18322)
 + * Update legacy peers tables during node replacement (CASSANDRA-19782)
 + * Refactor ColumnCondition (CASSANDRA-19620)
 + * Allow configuring log format for Audit Logs (CASSANDRA-19792)
 + * Support for noboolean rpm (centos7 compatible) packages removed 
(CASSANDRA-19787)
 + * Allow threads waiting for the metadata log follower to be interrupted 
(CASSANDRA-19761)
 + * Support dictionary lookup for CassandraPasswordValidator (CASSANDRA-19762)
 + * Disallow denylisting keys in system_cluster_metadata (CASSANDRA-19713)
 + * Fix gossip status after replacement (CASSANDRA-19712)
 + * Ignore repair requests for system_cluster_metadata (CASSANDRA-19711)
 + * Avoid ClassCastException when verifying tables with reversed partitioner 
(CASSANDRA-19710)
 + * Always repair the full range when repairing system_cluster_metadata 
(CASSANDRA-19709)
 + * Use table-specific partitioners during Paxos repair (CASSANDRA-19714)
 + * Expose current compaction throughput in nodetool (CASSANDRA-13890)
 + * CEP-24 Password validation / generation (CASSANDRA-17457)
 + * Reconfigure CMS after replacement, bootstrap and move operations 
(CASSANDRA-19705)
 + * Support querying LocalStrategy tables with any partitioner 
(CASSANDRA-19692)
 + * Relax slow_query_log_timeout for MultiNodeSAITest (CASSANDRA-19693)
 + * Audit Log entries are missing identity for mTLS connections 
(CASSANDRA-19669)
 + * Add support for the BETWEEN operator in WHERE clauses (CASSANDRA-19604)
 + * Replace Stream iteration with for-loop for 
SimpleRestriction::bindAndGetClusteringElements (CASSANDRA-19679)
 + * Consolidate logging on trace level (CASSANDRA-19632)
 + * Expand DDL statements on coordinator before submission to the CMS 
(CASSANDRA-19592)
 + * Fix number of arguments of String.format() in various classes 
(CASSANDRA-19645)
 + * Remove unused fields from config (CASSANDRA-19599)
 + * Refactor Relation and Restriction hierarchies (CASSANDRA-19341)
 + * Raise priority of TCM internode messages during critical operations 
(CASSANDRA-19517)
 + * Add nodetool command to unregister LEFT nodes (CASSANDRA-19581)
 + * Add cluster metadata id to gossip syn messages (CASSANDRA-19613)
 + * Reduce heap usage occupied by the metrics (CASSANDRA-19567)
 + * Improve handling of transient replicas during range movements 
(CASSANDRA-19344)
 + * Enable debounced internode log requests to be cancelled at shutdown 
(CASSANDRA-19514)
 + * Correctly set last modified epoch when combining multistep operations into 
a single step (CASSANDRA-19538)
 + * Add new TriggersPolicy configuration to allow operators to disable 
triggers (CASSANDRA-19532)
 + * Use Transformation.Kind.id in local and distributed log tables 
(CASSANDRA-19516)
 + * Remove period field from ClusterMetadata and metadata log tables 
(CASSANDRA-19482)
 + * Enrich system_views.pending_hints vtable with hints sizes (CASSANDRA-19486)
 + * Expose all dropwizard metrics in virtual tables (CASSANDRA-14572)
 + * Ensured that PropertyFileSnitchTest do not overwrite 
cassandra-toploogy.properties (CASSANDRA-19502)
 + * Add option for MutualTlsAuthenticator to restrict the certificate validity 
period (CASSANDRA-18951)
 + * Fix StorageService::constructRangeToEndpointMap for non-distributed 
keyspaces (CASSANDRA-19255)
 + * Group nodetool cms commands into single command group (CASSANDRA-19393)
 + * Register the measurements of the bootstrap process as Dropwizard metrics 
(CASSANDRA-19447)
 + * Add LIST SUPERUSERS CQL statement (CASSANDRA-19417)
 + * Modernize CQLSH datetime conversions (CASSANDRA-18879)
 + * Harry model and in-JVM tests for partition-restricted 2i queries 
(CASSANDRA-18275)
 + * Refactor cqlshmain global constants (CASSANDRA-19201)
 + * Remove native_transport_port_ssl (CASSANDRA-19397)
 + * Make nodetool reconfigurecms sync by default and add --cancel to be able 
to cancel ongoing reconfigurations (CASSANDRA-19216)
 + * Expose auth mode in system_views.clients, nodetool clientstats, metrics 
(CASSANDRA-19366)
 + * Remove sealed_periods and last_sealed_period tables (CASSANDRA-19189)
 + * Improve setup and initialisation of LocalLog/LogSpec (CASSANDRA-19271)
 + * Refactor structure of caching metrics and expose auth cache metrics via 
JMX (CASSANDRA-17062)
 + * Allow CQL client certificate authentication to work without sending an 
AUTHENTICATE request (CASSANDRA-18857)
 + * Extend nodetool tpstats and system_views.thread_pools with detailed pool 
parameters (CASSANDRA-19289)
 + * Remove dependency on Sigar in favor of OSHI (CASSANDRA-16565)
 + * Simplify the bind marker and Term logic (CASSANDRA-18813)
 + * Limit cassandra startup to supported JDKs, allow higher JDKs by setting 
CASSANDRA_JDK_UNSUPPORTED (CASSANDRA-18688)
 + * Standardize nodetool tablestats formatting of data units (CASSANDRA-19104)
 + * Make nodetool tablestats use number of significant digits for time and 
average values consistently (CASSANDRA-19015)
 + * Upgrade jackson to 2.15.3 and snakeyaml to 2.1 (CASSANDRA-18875)
 + * Transactional Cluster Metadata [CEP-21] (CASSANDRA-18330)
 + * Add ELAPSED command to cqlsh (CASSANDRA-18861)
 + * Add the ability to disable bulk loading of SSTables (CASSANDRA-18781)
 + * Clean up obsolete functions and simplify cql_version handling in cqlsh 
(CASSANDRA-18787)
 +Merged from 5.0:
+  * 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 --cc 
test/distributed/org/apache/cassandra/distributed/test/log/BounceIndexRebuildTest.java
index acf19d8fbf,0000000000..43bb78f44b
mode 100644,000000..100644
--- 
a/test/distributed/org/apache/cassandra/distributed/test/log/BounceIndexRebuildTest.java
+++ 
b/test/distributed/org/apache/cassandra/distributed/test/log/BounceIndexRebuildTest.java
@@@ -1,63 -1,0 +1,67 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.cassandra.distributed.test.log;
 +
++import org.apache.cassandra.distributed.test.sai.SAIUtil;
 +import org.junit.Assert;
 +import org.junit.Test;
 +
 +import org.apache.cassandra.distributed.Cluster;
 +import org.apache.cassandra.distributed.api.ConsistencyLevel;
 +import org.apache.cassandra.distributed.test.TestBaseImpl;
 +
++import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
++import static org.apache.cassandra.distributed.api.Feature.NETWORK;
 +import static org.junit.Assert.assertEquals;
 +
 +public class BounceIndexRebuildTest extends TestBaseImpl
 +{
 +    @Test
 +    public void bounceTest() throws Exception
 +    {
-         try (Cluster cluster = init(builder().withNodes(1)
-                                              .start()))
++        try (Cluster cluster = init(builder().withNodes(1).withConfig(config 
-> config.with(NETWORK, GOSSIP)).start()))
 +        {
 +            cluster.schemaChange(withKeyspace("create table %s.tbl (id int 
primary key, x int)"));
 +            for (int i = 0; i < 10; i++)
 +                cluster.coordinator(1).execute(withKeyspace("insert into 
%s.tbl (id, x) values (?, ?)"), ConsistencyLevel.ALL, i, i);
 +
-             cluster.schemaChange(withKeyspace("create index idx on %s.tbl 
(x)"));
++            cluster.schemaChange(withKeyspace("create index idx on %s.tbl (x) 
using 'sai'"));
++            SAIUtil.waitForIndexQueryable(cluster, KEYSPACE);
++
 +            Object[][] res = 
cluster.coordinator(1).execute(withKeyspace("select * from %s.tbl where x=5"), 
ConsistencyLevel.ALL);
 +            assert res.length > 0;
 +            String patternLegacyBuild = "Index build of idx complete";
 +            int preBounceLegacyBuilds = 
cluster.get(1).logs().grep(patternLegacyBuild).getResult().size();
 +
 +            final String patternSaiValidation = "Validating per-column index 
components for distributed_test_keyspace.idx";
 +            int preBounceSaiValidations = 
cluster.get(1).logs().grep(patternSaiValidation).getResult().size();
 +
 +            cluster.get(1).shutdown().get();
 +            cluster.get(1).startup();
 +            // Make sure legacy index does not rebuild on restart
 +            assertEquals(preBounceLegacyBuilds, 
cluster.get(1).logs().grep(patternLegacyBuild).getResult().size());
 +            // If we are using SAI, we want the index to validate rather than 
build
 +            if (preBounceLegacyBuilds == 0)
 +                
Assert.assertTrue(cluster.get(1).logs().grep(patternSaiValidation).getResult().size()
 > preBounceSaiValidations);
 +
 +            res = cluster.coordinator(1).execute(withKeyspace("select * from 
%s.tbl where x=5"), ConsistencyLevel.ALL);
 +            assert res.length > 0;
 +        }
 +    }
 +}
diff --cc 
test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
index 5d3c9e11d7,d7aa4e48ab..7f9f745915
--- 
a/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
+++ 
b/test/unit/org/apache/cassandra/index/sai/cql/CompositePartitionKeyIndexTest.java
@@@ -26,10 -28,88 +28,99 @@@ import org.apache.cassandra.db.marshal.
  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.distributed.test.cql3.SingleNodeTableWalkTest;
  import org.apache.cassandra.index.sai.SAITester;
+ import org.apache.cassandra.utils.ByteBufferUtil;
  
  public class CompositePartitionKeyIndexTest extends SAITester
  {
++    /**
++     * Originally discovered by {@link SingleNodeTableWalkTest} with the 
following seeds:
++     * 8837255108450816265
++     * 1164443107607596330
++     * -6614981692374717168
++     * 1746205502103206170
++     */
+     @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)));
+     }
+ 
++    /**
++     * Originally discovered by {@link SingleNodeTableWalkTest} with seed 
-5732060315438955166
++     */
+     @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
      {
diff --cc 
test/unit/org/apache/cassandra/index/sai/cql/StaticColumnIndexTest.java
index faaf74f5c6,d9dec8e3a7..428cfe8ca8
--- 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 +20,10 @@@ package org.apache.cassandra.index.sai.
  
  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.distributed.test.cql3.SingleNodeTableWalkTest;
  import org.apache.cassandra.index.sai.SAITester;
  
  public class StaticColumnIndexTest extends SAITester
@@@ -71,4 -77,42 +78,45 @@@
  
          beforeAndAfterFlush(() -> assertRowCount(execute("SELECT * FROM %s 
WHERE pk = ? AND v1 > ? AND s1 = ?", 0, 2, 100), 3));
      }
+ 
++    /**
++     * Originally discovered by {@link SingleNodeTableWalkTest} with seed 
-464866883761188308
++     */
+     @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