Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/java/org/apache/cassandra/db/transform/RTBoundValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.apache.cassandra.db.transform;

import org.apache.cassandra.db.DecoratedKey;
import org.apache.cassandra.db.DeletionTime;
import org.apache.cassandra.db.partitions.UnfilteredPartitionIterator;
import org.apache.cassandra.db.rows.RangeTombstoneMarker;
Expand Down Expand Up @@ -51,27 +52,29 @@ public static UnfilteredPartitionIterator validate(UnfilteredPartitionIterator p

public static UnfilteredRowIterator validate(UnfilteredRowIterator partition, Stage stage, boolean enforceIsClosed)
{
return Transformation.apply(partition, new RowsTransformation(stage, partition.metadata(), partition.isReverseOrder(), enforceIsClosed));
return Transformation.apply(partition, new RowsTransformation(stage, partition.partitionKey(), partition.metadata(), partition.isReverseOrder(), enforceIsClosed));
}

@Override
public UnfilteredRowIterator applyToPartition(UnfilteredRowIterator partition)
{
return Transformation.apply(partition, new RowsTransformation(stage, partition.metadata(), partition.isReverseOrder(), enforceIsClosed));
return Transformation.apply(partition, new RowsTransformation(stage, partition.partitionKey(), partition.metadata(), partition.isReverseOrder(), enforceIsClosed));
}

private final static class RowsTransformation extends Transformation
{
private final Stage stage;
private final DecoratedKey partitionKey;
private final TableMetadata metadata;
private final boolean isReverseOrder;
private final boolean enforceIsClosed;

private DeletionTime openMarkerDeletionTime;

private RowsTransformation(Stage stage, TableMetadata metadata, boolean isReverseOrder, boolean enforceIsClosed)
private RowsTransformation(Stage stage, DecoratedKey partitionKey, TableMetadata metadata, boolean isReverseOrder, boolean enforceIsClosed)
{
this.stage = stage;
this.partitionKey = partitionKey;
this.metadata = metadata;
this.isReverseOrder = isReverseOrder;
this.enforceIsClosed = enforceIsClosed;
Expand Down Expand Up @@ -116,7 +119,12 @@ public void onPartitionClose()
private IllegalStateException ise(String why)
{
String message =
String.format("%s UnfilteredRowIterator for %s has an illegal RT bounds sequence: %s", stage, metadata, why);
String.format("%s UnfilteredRowIterator for %s (partition key: %s) has an illegal RT bounds sequence (isReverseOrder=%b): %s",
stage,
metadata,
metadata.partitionKeyType.getString(this.partitionKey.getKey()),
isReverseOrder,
Comment on lines +122 to +126
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ise() builds the exception message by calling metadata.partitionKeyType.getString(partitionKey.getKey()). This conversion can throw (e.g., corrupt/invalid key bytes) and would prevent the intended IllegalStateException from being thrown with useful context, potentially masking the original RT-bounds problem. Consider wrapping the conversion in a try/catch and falling back to something safe (e.g., token, hex, or "") as done in UnfilteredValidation.handleInvalid(...).

Copilot uses AI. Check for mistakes.
why);
throw new IllegalStateException(message);
}
}
Expand Down