CASSANDRA-21356: Fix same-timestamp tombstone/expiring-cell tie-break… - #4992
Draft
arjunashok wants to merge 1 commit into
Draft
CASSANDRA-21356: Fix same-timestamp tombstone/expiring-cell tie-break…#4992arjunashok wants to merge 1 commit into
arjunashok wants to merge 1 commit into
Conversation
… in cursor compaction
arjunashok
force-pushed
the
CASSANDRA-21356
branch
from
August 3, 2026 22:47
43d1735 to
cd20667
Compare
arjunashok
marked this pull request as ready for review
August 3, 2026 22:49
arjunashok
marked this pull request as draft
August 3, 2026 23:07
nitsanw
reviewed
Aug 4, 2026
nitsanw
left a comment
Contributor
There was a problem hiding this comment.
Please consider comments
Comment on lines
-831
to
+832
| boolean leftIsTombstone = !left.isExpiring(); // !isExpiring() == isTombstone(), but does not need to consider localDeletionTime() | ||
| boolean rightIsTombstone = !right.isExpiring(); | ||
| boolean leftIsTombstone = left.ttl() == LivenessInfo.NO_TTL; // ttl=0 → tombstone; ttl>0 → expiring | ||
| boolean rightIsTombstone = right.ttl() == LivenessInfo.NO_TTL; |
Contributor
There was a problem hiding this comment.
The code here is a mirror of Cells.resolveRegular, I think it should be kept as is
Comment on lines
+49
to
+50
| // Check for TTL (not localExpirationTime as it will incorrectly return true for tombstones) | ||
| // Matches AbstractCell.isExpiring(). |
Contributor
There was a problem hiding this comment.
Good fix, I would add a link to AbstractCell.isExpiring() to the method javadoc, but remove the rest of the comment as it only explains the commit and not the code.
| * nothing to do with this bug — a byte-for-byte comparison here would fail regardless of whether | ||
| * this specific bug is fixed, so this test checks queryable behavior instead. | ||
| */ | ||
| public class CursorCompactionEquivalenceTest extends CQLTester |
Contributor
There was a problem hiding this comment.
Can we not add this test to one of the simple compaction test suites? smaller diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
… in cursor compaction
CASSANDRA-21356: Fix same-timestamp tombstone/expiring-cell tie-break in cursor compaction
What's the issue
ReusableLivenessInfo.isExpiring()checkedlocalExpirationTime != NO_EXPIRATION_TIMEinstead ofttl != NO_TTL. Tombstone cells also setlocalExpirationTime(stores the deletion timestamp there), so the check returnedtruefor tombstones as well as genuinely expiring cells.This broke
CursorCompactor.resolveRegular()'s logic for picking a winner when two cells have the exact same timestamp. That logic relies on!isExpiring()to tell tombstones apart from expiring cells.Since both now looked "expiring," it fell back to comparing
localExpirationTimedirectly. Now, the expiring cell's value there is a future timestamp, while the tombstone's is a past one, so the expiring cell always won.Net effect: an explicitly deleted column could be resurrected by cursor compaction if a same-timestamp write landed in another sstable.
Repro
Fix
Tests