Fix 2ndary index queries on partition keys for tables with static columns patch by Andrés de la Peña; reviewed by Benjamin Lerer for CASSANDRA-13147
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/64d8a1d9 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/64d8a1d9 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/64d8a1d9 Branch: refs/heads/trunk Commit: 64d8a1d9fdacf3e7396cdf2f5c61171c1c9bccf2 Parents: b021a1b Author: Andrés de la Peña <a.penya.gar...@gmail.com> Authored: Fri Apr 7 11:13:39 2017 +0200 Committer: Benjamin Lerer <b.le...@gmail.com> Committed: Fri Apr 7 11:15:54 2017 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cql3/statements/SelectStatement.java | 18 +++++++--- .../validation/entities/SecondaryIndexTest.java | 38 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/64d8a1d9/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 31c7b8a..eacd275 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.18 + * Fix 2ndary index queries on partition keys for tables with static columns (CASSANDRA-13147) * Fix ParseError unhashable type list in cqlsh copy from (CASSANDRA-13364) * Log stacktrace of uncaught exceptions (CASSANDRA-13108) * Remove unused repositories (CASSANDRA-13278) http://git-wip-us.apache.org/repos/asf/cassandra/blob/64d8a1d9/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index fe63b44..74fb201 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -1368,11 +1368,11 @@ public class SelectStatement implements CQLStatement CQL3Row.RowIterator iter = cfm.comparator.CQL3RowBuilder(cfm, now).group(cells); - // If there is static columns but there is no non-static row, then provided the select was a full - // partition selection (i.e. not a 2ndary index search and there was no condition on clustering columns) - // then we want to include the static columns in the result set (and we're done). + // If there is static columns but there is no non-static row, + // and the select was a full partition selection (i.e. there was no condition on clustering or regular columns), + // we want to include the static columns in the result set (and we're done). CQL3Row staticRow = iter.getStaticRow(); - if (staticRow != null && !iter.hasNext() && !usesSecondaryIndexing && hasNoClusteringColumnsRestriction()) + if (staticRow != null && !iter.hasNext() && hasNoClusteringColumnsRestriction() && hasNoRegularColumnsRestriction()) { result.newRow(); for (ColumnDefinition def : selection.getColumns()) @@ -1452,6 +1452,16 @@ public class SelectStatement implements CQLStatement return true; } + private boolean hasNoRegularColumnsRestriction() + { + for (ColumnDefinition def : restrictedColumns.keySet()) + { + if (def.kind == ColumnDefinition.Kind.REGULAR) + return false; + } + return true; + } + private boolean needsPostQueryOrdering() { // We need post-query ordering only for queries with IN on the partition key and an ORDER BY. http://git-wip-us.apache.org/repos/asf/cassandra/blob/64d8a1d9/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java index 4a54a9a..b723f60 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java @@ -552,6 +552,29 @@ public class SecondaryIndexTest extends CQLTester } @Test + public void testIndexOnPartitionKeyWithStaticColumnAndNoRows() throws Throwable + { + createTable("CREATE TABLE %s (pk1 int, pk2 int, c int, s int static, v int, PRIMARY KEY((pk1, pk2), c))"); + createIndex("CREATE INDEX ON %s (pk2)"); + execute("INSERT INTO %s (pk1, pk2, c, s, v) VALUES (?, ?, ?, ?, ?)", 1, 1, 1, 9, 1); + execute("INSERT INTO %s (pk1, pk2, c, s, v) VALUES (?, ?, ?, ?, ?)", 1, 1, 2, 9, 2); + execute("INSERT INTO %s (pk1, pk2, s) VALUES (?, ?, ?)", 2, 1, 9); + execute("INSERT INTO %s (pk1, pk2, c, s, v) VALUES (?, ?, ?, ?, ?)", 3, 1, 1, 9, 1); + + assertRows(execute("SELECT * FROM %s WHERE pk2 = ?", 1), + row(2, 1, null, 9, null), + row(1, 1, 1, 9, 1), + row(1, 1, 2, 9, 2), + row(3, 1, 1, 9, 1)); + + execute("UPDATE %s SET s=?, v=? WHERE pk1=? AND pk2=? AND c=?", 9, 1, 1, 10, 2); + assertRows(execute("SELECT * FROM %s WHERE pk2 = ?", 10), row(1, 10, 2, 9, 1)); + + execute("UPDATE %s SET s=? WHERE pk1=? AND pk2=?", 9, 1, 20); + assertRows(execute("SELECT * FROM %s WHERE pk2 = ?", 20), row(1, 20, null, 9, null)); + } + + @Test public void testIndexOnClusteringColumnInsertValueOver64k() throws Throwable { createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY (a, b))"); @@ -781,4 +804,19 @@ public class SecondaryIndexTest extends CQLTester assertRows(execute("SELECT * FROM %s WHERE v = textAsBlob('');"), row(bytes("foo124"), EMPTY_BYTE_BUFFER)); } + + @Test + public void testIndexOnRegularColumnWithPartitionWithoutRows() throws Throwable + { + createTable("CREATE TABLE %s (pk int, c int, s int static, v int, PRIMARY KEY(pk, c))"); + createIndex("CREATE INDEX ON %s (v)"); + execute("INSERT INTO %s (pk, c, s, v) VALUES (?, ?, ?, ?)", 1, 1, 9, 1); + execute("INSERT INTO %s (pk, c, s, v) VALUES (?, ?, ?, ?)", 1, 2, 9, 2); + execute("INSERT INTO %s (pk, s) VALUES (?, ?)", 2, 9); + execute("INSERT INTO %s (pk, c, s, v) VALUES (?, ?, ?, ?)", 3, 1, 9, 1); + flush(); + execute("DELETE FROM %s WHERE pk = ? and c = ?", 3, 1); + assertRows(execute("SELECT * FROM %s WHERE v = ?", 1), + row(1, 1, 9, 1)); + } }