Merge branch 'cassandra-2.2' into cassandra-3.0
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/0020e79f Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/0020e79f Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/0020e79f Branch: refs/heads/cassandra-3.11 Commit: 0020e79f8e5b46f29537c65d3bdb27308acbff8b Parents: e2bdf99 3f45010 Author: Sam Tunnicliffe <s...@beobal.com> Authored: Mon Feb 20 11:50:40 2017 +0000 Committer: Sam Tunnicliffe <s...@beobal.com> Committed: Mon Feb 20 12:00:25 2017 +0000 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/service/QueryPagerTest.java | 82 +++++++++++++++++++- 2 files changed, 79 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/0020e79f/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index af06a02,7073356..922e7f7 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,48 -1,8 +1,49 @@@ -2.2.10 +3.0.12 +Merged from 2.2 + * Fix ColumnCounter::countAll behaviour for reverse queries (CASSANDRA-13222) * Exceptions encountered calling getSeeds() breaks OTC thread (CASSANDRA-13018) -2.2.9 +3.0.11 + * Use keyspace replication settings on system.size_estimates table (CASSANDRA-9639) + * Add vm.max_map_count StartupCheck (CASSANDRA-13008) + * Hint related logging should include the IP address of the destination in addition to + host ID (CASSANDRA-13205) + * Reloading logback.xml does not work (CASSANDRA-13173) + * Lightweight transactions temporarily fail after upgrade from 2.1 to 3.0 (CASSANDRA-13109) + * Duplicate rows after upgrading from 2.1.16 to 3.0.10/3.9 (CASSANDRA-13125) + * Fix UPDATE queries with empty IN restrictions (CASSANDRA-13152) + * Abort or retry on failed hints delivery (CASSANDRA-13124) + * Fix handling of partition with partition-level deletion plus + live rows in sstabledump (CASSANDRA-13177) + * Provide user workaround when system_schema.columns does not contain entries + for a table that's in system_schema.tables (CASSANDRA-13180) + * Dump threads when unit tests time out (CASSANDRA-13117) + * Better error when modifying function permissions without explicit keyspace (CASSANDRA-12925) + * Indexer is not correctly invoked when building indexes over sstables (CASSANDRA-13075) + * Read repair is not blocking repair to finish in foreground repair (CASSANDRA-13115) + * Stress daemon help is incorrect (CASSANDRA-12563) + * Remove ALTER TYPE support (CASSANDRA-12443) + * Fix assertion for certain legacy range tombstone pattern (CASSANDRA-12203) + * Set javac encoding to utf-8 (CASSANDRA-11077) + * Replace empty strings with null values if they cannot be converted (CASSANDRA-12794) + * Fixed flacky SSTableRewriterTest: check file counts before calling validateCFS (CASSANDRA-12348) + * Fix deserialization of 2.x DeletedCells (CASSANDRA-12620) + * Add parent repair session id to anticompaction log message (CASSANDRA-12186) + * Improve contention handling on failure to acquire MV lock for streaming and hints (CASSANDRA-12905) + * Fix DELETE and UPDATE queries with empty IN restrictions (CASSANDRA-12829) + * Mark MVs as built after successful bootstrap (CASSANDRA-12984) + * Estimated TS drop-time histogram updated with Cell.NO_DELETION_TIME (CASSANDRA-13040) + * Nodetool compactionstats fails with NullPointerException (CASSANDRA-13021) + * Thread local pools never cleaned up (CASSANDRA-13033) + * Set RPC_READY to false when draining or if a node is marked as shutdown (CASSANDRA-12781) + * Make sure sstables only get committed when it's safe to discard commit log records (CASSANDRA-12956) + * Reject default_time_to_live option when creating or altering MVs (CASSANDRA-12868) + * Nodetool should use a more sane max heap size (CASSANDRA-12739) + * LocalToken ensures token values are cloned on heap (CASSANDRA-12651) + * AnticompactionRequestSerializer serializedSize is incorrect (CASSANDRA-12934) + * Prevent reloading of logback.xml from UDF sandbox (CASSANDRA-12535) + * Reenable HeapPool (CASSANDRA-12900) +Merged from 2.2: * Coalescing strategy sleeps too much and shouldn't be enabled by default (CASSANDRA-13090) * Fix negative mean latency metric (CASSANDRA-12876) * Use only one file pointer when creating commitlog segments (CASSANDRA-12539) http://git-wip-us.apache.org/repos/asf/cassandra/blob/0020e79f/test/unit/org/apache/cassandra/service/QueryPagerTest.java ---------------------------------------------------------------------- diff --cc test/unit/org/apache/cassandra/service/QueryPagerTest.java index bfc66e0,33a7585..34f1bcf --- a/test/unit/org/apache/cassandra/service/QueryPagerTest.java +++ b/test/unit/org/apache/cassandra/service/QueryPagerTest.java @@@ -26,25 -26,25 +26,28 @@@ import org.junit.BeforeClass import org.junit.Test; import org.junit.runner.RunWith; -import org.apache.cassandra.Util; -import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.OrderedJUnit4ClassRunner; +import org.apache.cassandra.*; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.KSMetaData; ++import org.apache.cassandra.config.ColumnDefinition; ++import org.apache.cassandra.cql3.ColumnIdentifier; import org.apache.cassandra.db.*; -import org.apache.cassandra.db.composites.*; ++import org.apache.cassandra.db.rows.Cell; +import org.apache.cassandra.db.rows.Row; +import org.apache.cassandra.db.rows.RowIterator; import org.apache.cassandra.db.filter.*; -import org.apache.cassandra.db.marshal.CompositeType; -import org.apache.cassandra.dht.*; +import org.apache.cassandra.db.partitions.FilteredPartition; +import org.apache.cassandra.db.partitions.PartitionIterator; import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.cassandra.locator.SimpleStrategy; -import org.apache.cassandra.service.pager.*; +import org.apache.cassandra.schema.KeyspaceParams; +import org.apache.cassandra.service.pager.QueryPager; +import org.apache.cassandra.service.pager.PagingState; import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.transport.Server; -import static org.junit.Assert.*; import static org.apache.cassandra.cql3.QueryProcessor.executeInternal; -import static org.apache.cassandra.Util.range; import static org.apache.cassandra.utils.ByteBufferUtil.bytes; +import static org.junit.Assert.*; @RunWith(OrderedJUnit4ClassRunner.class) public class QueryPagerTest @@@ -53,22 -53,31 +56,30 @@@ public static final String CF_STANDARD = "Standard1"; public static final String KEYSPACE_CQL = "cql_keyspace"; public static final String CF_CQL = "table2"; + public static final String CF_CQL_WITH_STATIC = "with_static"; + public static final int nowInSec = FBUtilities.nowInSeconds(); @BeforeClass public static void defineSchema() throws ConfigurationException { SchemaLoader.prepareServer(); SchemaLoader.createKeyspace(KEYSPACE1, - SimpleStrategy.class, - KSMetaData.optsWithRF(1), + KeyspaceParams.simple(1), SchemaLoader.standardCFMD(KEYSPACE1, CF_STANDARD)); SchemaLoader.createKeyspace(KEYSPACE_CQL, - SimpleStrategy.class, - KSMetaData.optsWithRF(1), + KeyspaceParams.simple(1), CFMetaData.compile("CREATE TABLE " + CF_CQL + " (" - + "k text," - + "c text," - + "v text," - + "PRIMARY KEY (k, c))", KEYSPACE_CQL)); + + "k text," + + "c text," + + "v text," + + "PRIMARY KEY (k, c))", KEYSPACE_CQL), + CFMetaData.compile("CREATE TABLE " + CF_CQL_WITH_STATIC + " (" + + "pk text, " + + "ck int, " + + "st int static, " + + "v1 int, " + + "v2 int, " + + "PRIMARY KEY(pk, ck))", KEYSPACE_CQL)); addData(); } @@@ -432,9 -380,52 +443,72 @@@ for (int i = 0; i < 5; i++) { - List<Row> page = pager.fetchPage(1); - assertEquals(toString(page), 1, page.size()); + List<FilteredPartition> partitions = query(pager, 1); // The only live cell we should have each time is the row marker - assertRow(page.get(0), "k0", ct.decompose("c" + i, "")); + assertRow(partitions.get(0), "k0", "c" + i); } } + + @Test + public void pagingReversedQueriesWithStaticColumnsTest() throws Exception + { ++ // There was a bug in paging for reverse queries when the schema includes static columns in ++ // 2.1 & 2.2. This was never a problem in 3.0, this test just guards against regressions ++ // see CASSANDRA-13222 ++ + // insert some rows into a single partition + for (int i=0; i < 5; i++) + executeInternal(String.format("INSERT INTO %s.%s (pk, ck, st, v1, v2) VALUES ('k0', %3$s, %3$s, %3$s, %3$s)", + KEYSPACE_CQL, CF_CQL_WITH_STATIC, i)); + + // query the table in reverse with page size = 1 & check that the returned rows contain the correct cells + CFMetaData cfm = Keyspace.open(KEYSPACE_CQL).getColumnFamilyStore(CF_CQL_WITH_STATIC).metadata; + queryAndVerifyCells(cfm, true, "k0"); + } + + private void queryAndVerifyCells(CFMetaData cfm, boolean reversed, String key) throws Exception + { - SliceQueryFilter filter = new SliceQueryFilter(ColumnSlice.ALL_COLUMNS_ARRAY, reversed, 100, 1); - QueryPager pager = QueryPagers.localPager(new SliceFromReadCommand(cfm.ksName, bytes(key), cfm.cfName, 0, filter)); - CellName staticCellName = cfm.comparator.create(cfm.comparator.staticPrefix(), - cfm.staticColumns().iterator().next()); ++ ClusteringIndexFilter rowfilter = new ClusteringIndexSliceFilter(Slices.ALL, reversed); ++ ReadCommand command = SinglePartitionReadCommand.create(cfm, nowInSec, Util.dk(key), ColumnFilter.all(cfm), rowfilter); ++ QueryPager pager = command.getPager(null, Server.CURRENT_VERSION); ++ ++ ColumnDefinition staticColumn = cfm.partitionColumns().statics.getSimple(0); ++ assertEquals(staticColumn.name.toCQLString(), "st"); ++ + for (int i=0; i<5; i++) + { - List<Row> page = pager.fetchPage(1); - assertEquals(1, page.size()); - Row row = page.get(0); - assertCell(row.cf, staticCellName, 4); - int cellIndex = !reversed ? i : 4 - i; - assertCell(row.cf, Util.cellname(ByteBufferUtil.bytes(cellIndex), ByteBufferUtil.bytes("v1")), cellIndex); - assertCell(row.cf, Util.cellname(ByteBufferUtil.bytes(cellIndex), ByteBufferUtil.bytes("v2")), cellIndex); ++ try (ReadOrderGroup orderGroup = pager.startOrderGroup(); ++ PartitionIterator partitions = pager.fetchPageInternal(1, orderGroup)) ++ { ++ try (RowIterator partition = partitions.next()) ++ { ++ assertCell(partition.staticRow(), staticColumn, 4); ++ ++ Row row = partition.next(); ++ int cellIndex = !reversed ? i : 4 - i; ++ ++ assertEquals(row.clustering().get(0), ByteBufferUtil.bytes(cellIndex)); ++ assertCell(row, cfm.getColumnDefinition(new ColumnIdentifier("v1", false)), cellIndex); ++ assertCell(row, cfm.getColumnDefinition(new ColumnIdentifier("v2", false)), cellIndex); ++ ++ // the partition/page should contain just a single regular row ++ assertFalse(partition.hasNext()); ++ } ++ } + } + + // After processing the 5 rows there should be no more rows to return - List<Row> page = pager.fetchPage(1); - assertTrue(page.isEmpty()); ++ try ( ReadOrderGroup orderGroup = pager.startOrderGroup(); ++ PartitionIterator partitions = pager.fetchPageInternal(1, orderGroup)) ++ { ++ assertFalse(partitions.hasNext()); ++ } + } + - private void assertCell(ColumnFamily cf, CellName cellName, int value) ++ private void assertCell(Row row, ColumnDefinition column, int value) + { - Cell cell = cf.getColumn(cellName); ++ Cell cell = row.getCell(column); + assertNotNull(cell); + assertEquals(value, ByteBufferUtil.toInt(cell.value())); + } }