dcapwell commented on PR #3731:
URL: https://github.com/apache/cassandra/pull/3731#issuecomment-2560427817

   I applied the patch to the branch that found the problem, and applied the 
feedback I gave and the test that found the issue is passing now!
   
   Here is the modified version of this PR with my feedback applied
   
   ```
   diff --git a/src/java/org/apache/cassandra/db/filter/RowFilter.java 
b/src/java/org/apache/cassandra/db/filter/RowFilter.java
   index 9ea44ead96..ce96e8daa0 100644
   --- a/src/java/org/apache/cassandra/db/filter/RowFilter.java
   +++ b/src/java/org/apache/cassandra/db/filter/RowFilter.java
   @@ -224,7 +224,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
    
                    // Short-circuit all partitions that won't match based on 
static and partition keys
                    for (Expression e : partitionLevelExpressions)
   -                    if (!e.isSatisfiedBy(metadata, 
partition.partitionKey(), partition.staticRow()))
   +                    if (!e.isSatisfiedBy(metadata, 
partition.partitionKey(), partition.staticRow(), nowInSec))
                        {
                            partition.close();
                            return null;
   @@ -251,7 +251,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                        return null;
    
                    for (Expression e : rowLevelExpressions)
   -                    if (!e.isSatisfiedBy(metadata, pk, purged))
   +                    if (!e.isSatisfiedBy(metadata, pk, purged, nowInSec))
                            return null;
    
                    return row;
   @@ -303,7 +303,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
    
            for (Expression e : expressions)
            {
   -            if (!e.isSatisfiedBy(metadata, partitionKey, purged))
   +            if (!e.isSatisfiedBy(metadata, partitionKey, purged, nowInSec))
                    return false;
            }
            return true;
   @@ -522,9 +522,9 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
             * (i.e. it should come from a RowIterator).
             * @return whether the row is satisfied by this expression.
             */
   -        public abstract boolean isSatisfiedBy(TableMetadata metadata, 
DecoratedKey partitionKey, Row row);
   +        public abstract boolean isSatisfiedBy(TableMetadata metadata, 
DecoratedKey partitionKey, Row row, long nowInSec);
    
   -        protected ByteBuffer getValue(TableMetadata metadata, DecoratedKey 
partitionKey, Row row)
   +        protected ByteBuffer getValue(TableMetadata metadata, DecoratedKey 
partitionKey, Row row, long nowInSec)
            {
                switch (column.kind)
                {
   @@ -536,7 +536,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                        return row.clustering().bufferAt(column.position());
                    default:
                        Cell<?> cell = row.getCell(column);
   -                    return cell == null ? null : cell.buffer();
   +                    return Cell.getValidCellBuffer(cell, nowInSec);
                }
            }
    
   @@ -697,7 +697,8 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                super(column, operator, value);
            }
    
   -        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row)
   +        @Override
   +        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row, long nowInSec)
            {
                // We support null conditions for LWT (in ColumnCondition) but 
not for RowFilter.
                // TODO: we should try to merge both code someday.
   @@ -711,7 +712,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                    // representation. See CASSANDRA-11629
                    if (column.type.isCounter())
                    {
   -                    ByteBuffer foundValue = getValue(metadata, 
partitionKey, row);
   +                    ByteBuffer foundValue = getValue(metadata, 
partitionKey, row, nowInSec);
                        if (foundValue == null)
                            return false;
    
   @@ -721,7 +722,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                    else
                    {
                        // Note that CQL expression are always of the form 'x < 
4', i.e. the tested value is on the left.
   -                    ByteBuffer foundValue = getValue(metadata, 
partitionKey, row);
   +                    ByteBuffer foundValue = getValue(metadata, 
partitionKey, row, nowInSec);
                        return foundValue != null && 
operator.isSatisfiedBy(column.type, foundValue, value);
                    }
                }
   @@ -736,7 +737,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                    }
                    else
                    {
   -                    ByteBuffer foundValue = getValue(metadata, 
partitionKey, row);
   +                    ByteBuffer foundValue = getValue(metadata, 
partitionKey, row, nowInSec);
                        return foundValue != null && 
operator.isSatisfiedBy(column.type, foundValue, value);
                    }
                }
   @@ -821,7 +822,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                return CompositeType.build(ByteBufferAccessor.instance, key, 
value);
            }
    
   -        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row)
   +        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row, long nowInSec)
            {
                assert key != null;
                // We support null conditions for LWT (in ColumnCondition) but 
not for RowFilter.
   @@ -839,7 +840,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
                }
                else
                {
   -                ByteBuffer serializedMap = getValue(metadata, partitionKey, 
row);
   +                ByteBuffer serializedMap = getValue(metadata, partitionKey, 
row, nowInSec);
                    if (serializedMap == null)
                        return false;
    
   @@ -940,7 +941,7 @@ public class RowFilter implements 
Iterable<RowFilter.Expression>
            }
    
            // Filtering by custom expressions isn't supported yet, so just 
accept any row
   -        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row)
   +        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row, long nowInSec)
            {
                return true;
            }
   diff --git a/src/java/org/apache/cassandra/db/rows/Cell.java 
b/src/java/org/apache/cassandra/db/rows/Cell.java
   index 3ddfeae39a..f7ecb5c8fb 100644
   --- a/src/java/org/apache/cassandra/db/rows/Cell.java
   +++ b/src/java/org/apache/cassandra/db/rows/Cell.java
   @@ -240,6 +240,26 @@ public abstract class Cell<V> extends ColumnData
                                               // timestamp on expiry.
        }
    
   +    /**
   +     * Validates a cell's liveliness, tombstone status, and buffer contents.
   +     *
   +     * @param cell         The cell to validate.
   +     * @param nowInSeconds The current time in seconds.
   +     * @return A ByteBuffer (including valid empty buffers) if valid, or 
null otherwise.
   +     */
   +    public static ByteBuffer getValidCellBuffer(Cell<?> cell, long 
nowInSeconds) {
   +        if (cell == null || cell.isTombstone()) {
   +            return null;
   +        }
   +
   +        if (!cell.isLive(nowInSeconds)) {
   +            return null;
   +        }
   +
   +        // Allow valid empty buffers
   +        return cell.buffer();
   +    }
   +
        /**
         * The serialization format for cell is:
         *     [ flags ][ timestamp ][ deletion time ][    ttl    ][ path size 
][ path ][ value size ][ value ]
   diff --git 
a/test/unit/org/apache/cassandra/index/sai/plan/OperationTest.java 
b/test/unit/org/apache/cassandra/index/sai/plan/OperationTest.java
   index 8b0acaaf2b..81292cbda0 100644
   --- a/test/unit/org/apache/cassandra/index/sai/plan/OperationTest.java
   +++ b/test/unit/org/apache/cassandra/index/sai/plan/OperationTest.java
   @@ -515,7 +515,7 @@ public class OperationTest
            }
    
            @Override
   -        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row)
   +        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row, long nowInSec)
            {
                throw new UnsupportedOperationException();
            }
   diff --git 
a/test/unit/org/apache/cassandra/index/sasi/plan/OperationTest.java 
b/test/unit/org/apache/cassandra/index/sasi/plan/OperationTest.java
   index 79c86b977f..d8bc539c71 100644
   --- a/test/unit/org/apache/cassandra/index/sasi/plan/OperationTest.java
   +++ b/test/unit/org/apache/cassandra/index/sasi/plan/OperationTest.java
   @@ -651,7 +651,7 @@ public class OperationTest extends SchemaLoader
            }
    
            @Override
   -        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row)
   +        public boolean isSatisfiedBy(TableMetadata metadata, DecoratedKey 
partitionKey, Row row, long nowInSec)
            {
                throw new UnsupportedOperationException();
            }
   
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to