[ 
https://issues.apache.org/jira/browse/CASSANDRA-21307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18107530#comment-18107530
 ] 

Francisco Guerrero commented on CASSANDRA-21307:
------------------------------------------------

It looks like this was fixed as part of CASSANDRA-21255, specifically here: 
https://github.com/apache/cassandra/commit/10ca003dd21fda1969173e8bfdd8c1303f616faa#diff-7a8221663940050db446c9df287194fd8301db37225be952b1ef5b6c2aa047f3R604

> Lower bound [SSTABLE_UPPER_BOUND(row000063)] is bigger than first returned 
> value
> --------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-21307
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21307
>             Project: Apache Cassandra
>          Issue Type: Bug
>            Reporter: Alex Petrov
>            Assignee: Alex Petrov
>            Priority: Normal
>
> {code}
> package org.apache.cassandra.db;
> import org.junit.Before;
> import org.junit.Test;
> import org.apache.cassandra.config.DatabaseDescriptor;
> import org.apache.cassandra.cql3.CQLTester;
> /**
> * Reproduces a bug in SSTableCursorWriter.addIndexBlock() where the sentinel 
> check
> * clusteringLength() == 0 incorrectly matches an INCL_END_BOUND (TOP) marker 
> with 0 components.
> *
> * When the last item in a column index block is TOP (INCL_END_BOUND with 0 
> components),
> * addIndexBlock() mistakes it for "no IndexInfo#lastName set" (the sentinel 
> after resetClustering() also has
> * clusteringLength==0 but kind==CLUSTERING, while TOP has 
> kind==INCL_END_BOUND). This causes the
> * block's IndexInfo#lastName to be set to IndexInfo#firstName instead of TOP.
> *
> * When a reversed (DESC) scan reads the resulting SSTable, 
> getLowerBoundPrefixFromCache()
> * returns SSTABLE_UPPER_BOUND(IndexInfo#firstName) as the lower bound, but 
> the first item
> * actually returned is TOP (INCL_END_BOUND with 0 components). In reversed 
> order,
> * TOP > any specific bound, so the assertion
> * "Lower bound is bigger than first returned value" fires.
> *
> * The fix: change the sentinel in addIndexBlock() from
> *   clusteringLength() == 0
> * to
> *   clusteringKind() == CLUSTERING && clusteringLength() == 0
> *
> * Trigger conditions (all must hold):
> * 1. The partition has enough data for at least 3 column index blocks 
> (rowIndexEntriesOffsets.size() > 1)
> * 2. The range tombstone extends to the top of the partition (INCL_END_BOUND 
> with 0 components = TOP)
> * 3. TOP lands in the LAST block (not as the sole item in its own block)
> * 4. Two SSTables must be compacted (rows in one SSTable, tombstone in 
> another)
> */
> public class RangeTombstoneReproTest extends CQLTester
> {
>    @Before
>    public void setUp()
>    {
>        DatabaseDescriptor.setColumnIndexSizeInKiB(1);
>    }
>    @Test
>    public void testDescScanAfterCompactionWithOpenEndedRangeTombstone() 
> throws Throwable
>    {
>        // Need enough rows to produce >= 2 finalized 1 KiB column index 
> blocks.
>        // Each row ~32 bytes → 32 rows per block → 64 rows → 2 complete 
> blocks + partial last block with tombstone.
>        createTable("CREATE TABLE %s (pk text, ck text, v text, PRIMARY KEY 
> (pk, ck))");
>        ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
>        cfs.disableAutoCompaction();
>        String pk = "pk0";
>        for (int i = 0; i < 64; i++)
>        {
>            String ck = String.format("row%06d", i);
>            execute("INSERT INTO %s (pk, ck, v) VALUES (?, ?, ?)", pk, ck, 
> "value_" + ck);
>        }
>        flush();
>        // Open-ended tombstone: INCL_END_BOUND() = TOP (0 components) lands 
> in the last block.
>        // Must be in a separate SSTable; single-SSTable compaction does not 
> trigger the bug.
>        execute("DELETE FROM %s WHERE pk = ? AND ck >= 'z'", pk);
>        flush();
>        // Compact the 2 SSTables; writes buggy RowIndexEntry (wrong 
> IndexInfo#lastName in last block)
>        cfs.forceMajorCompaction();
>        // DESC scan reads the SSTable, computes lower bound from the buggy 
> RowIndexEntry,
>        // and asserts: "Lower bound [SSTABLE_UPPER_BOUND(row000063)] is 
> bigger than first returned value
>        // [Marker INCL_END_BOUND()]"
>        execute("SELECT * FROM %s WHERE pk = ? ORDER BY ck DESC", pk);
>    }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

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

Reply via email to