diff --git a/CHANGES.txt b/CHANGES.txt index b4364bab20..aeae5e8fd5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,7 @@ * Let CassandraVersion handle SNAPSHOT version (CASSANDRA-9438) Merged from 2.1: 2.1.6 + * Fix empty partition assertion in unsorted sstable writing tools (CASSANDRA-9071) * Ensure truncate without snapshot cannot produce corrupt responses (CASSANDRA-9388) * Consistent error message when a table mixes counter and non-counter columns (CASSANDRA-9492) diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableSimpleUnsortedWriter.java b/src/java/org/apache/cassandra/io/sstable/SSTableSimpleUnsortedWriter.java index d6ab940867..cc47845c74 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTableSimpleUnsortedWriter.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTableSimpleUnsortedWriter.java @@ -176,6 +176,7 @@ public class SSTableSimpleUnsortedWriter extends AbstractSSTableSimpleWriter buffer = new Buffer(); currentSize = 0; columnFamily = getColumnFamily(); + buffer.setFirstInsertedKey(currentKey); } private void put(Buffer buffer) throws IOException @@ -208,7 +209,17 @@ public class SSTableSimpleUnsortedWriter extends AbstractSSTableSimpleWriter } // typedef - private static class Buffer extends TreeMap {} + private static class Buffer extends TreeMap { + private DecoratedKey firstInsertedKey; + + public void setFirstInsertedKey(DecoratedKey firstInsertedKey) { + this.firstInsertedKey = firstInsertedKey; + } + + public DecoratedKey getFirstInsertedKey() { + return firstInsertedKey; + } + } private class DiskWriter extends Thread { @@ -227,16 +238,14 @@ public class SSTableSimpleUnsortedWriter extends AbstractSSTableSimpleWriter try (SSTableWriter writer = getWriter();) { - boolean first = true; for (Map.Entry entry : b.entrySet()) { if (entry.getValue().getColumnCount() > 0) writer.append(entry.getKey(), entry.getValue()); - else if (!first) + else if (!entry.getKey().equals(b.getFirstInsertedKey())) throw new AssertionError("Empty partition"); - first = false; } - + writer.finish(false); } } diff --git a/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java b/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java index 6525527539..70d70ceb8b 100644 --- a/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java +++ b/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java @@ -22,6 +22,7 @@ import java.io.FilenameFilter; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Iterator; +import java.util.UUID; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; @@ -181,6 +182,34 @@ public class CQLSSTableWriterTest } + @Test + public void testSyncNoEmptyRows() throws Exception + { + // Check that the write does not throw an empty partition error (#9071) + File tempdir = Files.createTempDir(); + String schema = "CREATE TABLE ks.test2 (" + + " k UUID," + + " c int," + + " PRIMARY KEY (k)" + + ")"; + String insert = "INSERT INTO ks.test2 (k, c) VALUES (?, ?)"; + CQLSSTableWriter writer = CQLSSTableWriter.builder() + .inDirectory(tempdir) + .forTable(schema) + .withPartitioner(StorageService.instance.getPartitioner()) + .using(insert) + .withBufferSizeInMB(1) + .build(); + + for (int i = 0 ; i < 50000 ; i++) { + writer.addRow(UUID.randomUUID(), 0); + } + writer.close(); + + } + + + private static final int NUMBER_WRITES_IN_RUNNABLE = 10; private class WriterThread extends Thread {