Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.cassandra.schema.ColumnMetadata;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.Operator;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.filter.RowFilter;
import org.apache.cassandra.exceptions.InvalidRequestException;
Expand Down Expand Up @@ -206,6 +207,17 @@ public void addToRowFilter(RowFilter filter,

private boolean handleInFilter(SingleRestriction restriction, int index)
{
return restriction.needsFilteringOrIndexing() || index != restriction.firstColumn().position();
// Allow BETWEEN on the first clustering column to be handled via row filter
if (restriction instanceof SimpleRestriction)
{
SimpleRestriction sr = (SimpleRestriction) restriction;
if (sr.operator() == Operator.BETWEEN &&
index == sr.firstColumn().position())
{
return true;
}
}
// Default: require filtering or non‑leading‑column position
return restriction.needsFilteringOrIndexing() ||index != restriction.firstColumn().position();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,12 @@ public void addToRowFilter(RowFilter filter, IndexRegistry indexRegistry, QueryO
List<ByteBuffer> buffers = bindAndGet(options);
if (operator.kind() != Operator.Kind.BINARY)
{
// For BETWEEN we support like in SQL reversed bounds
if (operator.kind() == Operator.Kind.TERNARY)
// New: only sort IN‑list values; preserve order for BETWEEN
if (operator == Operator.IN)
{
// IN‑list bounds sorted for efficient lookup
buffers.sort(column.type);
}
filter.add(column, operator, multiInputOperatorValues(column, buffers));
}
else if (operator == Operator.LIKE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.apache.cassandra.distributed.test;

import org.apache.cassandra.distributed.Cluster;
import org.apache.cassandra.distributed.api.ConsistencyLevel;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
* Tests BETWEEN operator respects SQL semantics:
* - Normal BETWEEN (low <= high) returns rows.
* - Inverted BETWEEN (low > high) returns no rows.
*/
public class BetweenInversionTest
{
@Test
public void testBetweenInversion() throws Throwable
{
// Start a 1-node in-JVM cluster
try (Cluster cluster = Cluster.build(1).start())
{
cluster.schemaChange("CREATE KEYSPACE ks WITH replication = "
+ "{'class':'SimpleStrategy','replication_factor':1}");
cluster.schemaChange("CREATE TABLE ks.t1 (pk int PRIMARY KEY, val text)");

// Insert two rows
cluster.coordinator(1).execute("INSERT INTO ks.t1 (pk,val) VALUES (1,'a')", ConsistencyLevel.ALL);
cluster.coordinator(1).execute("INSERT INTO ks.t1 (pk,val) VALUES (2,'b')", ConsistencyLevel.ALL);

// Normal BETWEEN: should return 2 rows
Object[][] rows = cluster.coordinator(1)
.execute("SELECT * FROM ks.t1 WHERE pk BETWEEN 1 AND 2", ConsistencyLevel.ALL);
assertEquals(2, rows.length);

// Inverted BETWEEN: should return 0 rows
Object[][] inverted = cluster.coordinator(1)
.execute("SELECT * FROM ks.t1 WHERE pk BETWEEN 2 AND 1", ConsistencyLevel.ALL);
assertEquals(0, inverted.length);
}
}
}