mirror of https://github.com/apache/cassandra
Avoid potential NPE for queries with ORDER BY and IN
patch by blerer; reviewed by beobal for CASSANDRA-10955
This commit is contained in:
parent
0b479a7f3e
commit
deafdbe373
|
@ -1,4 +1,5 @@
|
|||
2.2.5
|
||||
* Fix potential NPE on ORDER BY queries with IN (CASSANDRA-10955)
|
||||
* Avoid over-fetching during the page of range queries (CASSANDRA-8521)
|
||||
* Start L0 STCS-compactions even if there is a L0 -> L1 compaction
|
||||
going (CASSANDRA-10979)
|
||||
|
|
|
@ -1092,10 +1092,21 @@ public class SelectStatement implements CQLStatement
|
|||
}
|
||||
}
|
||||
|
||||
private static abstract class ColumnComparator<T> implements Comparator<T>
|
||||
{
|
||||
protected final int compare(Comparator<ByteBuffer> comparator, ByteBuffer aValue, ByteBuffer bValue)
|
||||
{
|
||||
if (aValue == null)
|
||||
return bValue == null ? 0 : -1;
|
||||
|
||||
return bValue == null ? 1 : comparator.compare(aValue, bValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in orderResults(...) method when single 'ORDER BY' condition where given
|
||||
*/
|
||||
private static class SingleColumnComparator implements Comparator<List<ByteBuffer>>
|
||||
private static class SingleColumnComparator extends ColumnComparator<List<ByteBuffer>>
|
||||
{
|
||||
private final int index;
|
||||
private final Comparator<ByteBuffer> comparator;
|
||||
|
@ -1108,14 +1119,14 @@ public class SelectStatement implements CQLStatement
|
|||
|
||||
public int compare(List<ByteBuffer> a, List<ByteBuffer> b)
|
||||
{
|
||||
return comparator.compare(a.get(index), b.get(index));
|
||||
return compare(comparator, a.get(index), b.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in orderResults(...) method when multiple 'ORDER BY' conditions where given
|
||||
*/
|
||||
private static class CompositeComparator implements Comparator<List<ByteBuffer>>
|
||||
private static class CompositeComparator extends ColumnComparator<List<ByteBuffer>>
|
||||
{
|
||||
private final List<Comparator<ByteBuffer>> orderTypes;
|
||||
private final List<Integer> positions;
|
||||
|
@ -1133,10 +1144,7 @@ public class SelectStatement implements CQLStatement
|
|||
Comparator<ByteBuffer> type = orderTypes.get(i);
|
||||
int columnPos = positions.get(i);
|
||||
|
||||
ByteBuffer aValue = a.get(columnPos);
|
||||
ByteBuffer bValue = b.get(columnPos);
|
||||
|
||||
int comparison = type.compare(aValue, bValue);
|
||||
int comparison = compare(type, a.get(columnPos), b.get(columnPos));
|
||||
|
||||
if (comparison != 0)
|
||||
return comparison;
|
||||
|
|
|
@ -392,6 +392,49 @@ public class SelectOrderByTest extends CQLTester
|
|||
row("A"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrderByForInClauseWithNullValue() throws Throwable
|
||||
{
|
||||
createTable("CREATE TABLE %s (a int, b int, c int, s int static, d int, PRIMARY KEY (a, b, c))");
|
||||
|
||||
execute("INSERT INTO %s (a, b, c, d) VALUES (1, 1, 1, 1)");
|
||||
execute("INSERT INTO %s (a, b, c, d) VALUES (1, 1, 2, 1)");
|
||||
execute("INSERT INTO %s (a, b, c, d) VALUES (2, 2, 1, 1)");
|
||||
execute("INSERT INTO %s (a, b, c, d) VALUES (2, 2, 2, 1)");
|
||||
|
||||
execute("UPDATE %s SET s = 1 WHERE a = 1");
|
||||
execute("UPDATE %s SET s = 2 WHERE a = 2");
|
||||
execute("UPDATE %s SET s = 3 WHERE a = 3");
|
||||
|
||||
assertRows(execute("SELECT a, b, c, d, s FROM %s WHERE a IN (1, 2, 3) ORDER BY b DESC"),
|
||||
row(2, 2, 2, 1, 2),
|
||||
row(2, 2, 1, 1, 2),
|
||||
row(1, 1, 2, 1, 1),
|
||||
row(1, 1, 1, 1, 1),
|
||||
row(3, null, null, null, 3));
|
||||
|
||||
assertRows(execute("SELECT a, b, c, d, s FROM %s WHERE a IN (1, 2, 3) ORDER BY b ASC"),
|
||||
row(3, null, null, null, 3),
|
||||
row(1, 1, 1, 1, 1),
|
||||
row(1, 1, 2, 1, 1),
|
||||
row(2, 2, 1, 1, 2),
|
||||
row(2, 2, 2, 1, 2));
|
||||
|
||||
assertRows(execute("SELECT a, b, c, d, s FROM %s WHERE a IN (1, 2, 3) ORDER BY b DESC , c DESC"),
|
||||
row(2, 2, 2, 1, 2),
|
||||
row(2, 2, 1, 1, 2),
|
||||
row(1, 1, 2, 1, 1),
|
||||
row(1, 1, 1, 1, 1),
|
||||
row(3, null, null, null, 3));
|
||||
|
||||
assertRows(execute("SELECT a, b, c, d, s FROM %s WHERE a IN (1, 2, 3) ORDER BY b ASC, c ASC"),
|
||||
row(3, null, null, null, 3),
|
||||
row(1, 1, 1, 1, 1),
|
||||
row(1, 1, 2, 1, 1),
|
||||
row(2, 2, 1, 1, 2),
|
||||
row(2, 2, 2, 1, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reversed comparators
|
||||
* migrated from cql_tests.py:TestCQL.reversed_comparator_test()
|
||||
|
|
Loading…
Reference in New Issue