Repository: cassandra Updated Branches: refs/heads/cassandra-2.1 ea686198f -> 141b9399d refs/heads/cassandra-2.1.0 23233b384 -> 8137fce52 refs/heads/trunk 5233948d1 -> f0635da39
Handle CQL row marker in SSTableImport patch by Mikhail Stepura; reviewed by Tyler Hobbs for CASSANDRA-7477 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/8137fce5 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/8137fce5 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/8137fce5 Branch: refs/heads/cassandra-2.1 Commit: 8137fce529fe56db571d288e1e179aff905368de Parents: 23233b3 Author: Mikhail Stepura <mish...@apache.org> Authored: Thu Aug 14 16:31:17 2014 -0700 Committer: Mikhail Stepura <mish...@apache.org> Committed: Fri Aug 15 13:11:47 2014 -0700 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/tools/SSTableImport.java | 12 +++- test/resources/CQLTable.json | 10 ++++ .../cassandra/tools/SSTableImportTest.java | 62 +++++++++++++++++++- 4 files changed, 81 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/8137fce5/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 5b5283f..8714265 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.0-rc6 + * json2sstable couldn't import JSON for CQL table (CASSANDRA-7477) * Invalidate all caches on table drop (CASSANDRA-7561) * Skip strict endpoint selection for ranges if RF == nodes (CASSANRA-7765) * Fix Thrift range filtering without 2ary index lookups (CASSANDRA-7741) http://git-wip-us.apache.org/repos/asf/cassandra/blob/8137fce5/src/java/org/apache/cassandra/tools/SSTableImport.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/SSTableImport.java b/src/java/org/apache/cassandra/tools/SSTableImport.java index 4e7bf06..6e1415f 100644 --- a/src/java/org/apache/cassandra/tools/SSTableImport.java +++ b/src/java/org/apache/cassandra/tools/SSTableImport.java @@ -142,7 +142,11 @@ public class SSTableImport } else { - value = stringAsType((String) fields.get(1), meta.getValueValidator(comparator.cellFromByteBuffer(name))); + assert meta.isCQL3Table() || name.hasRemaining() : "Cell name should not be empty"; + value = stringAsType((String) fields.get(1), + meta.getValueValidator(name.hasRemaining() + ? comparator.cellFromByteBuffer(name) + : meta.comparator.rowMarker(Composites.EMPTY))); } } } @@ -215,8 +219,10 @@ public class SSTableImport cfamily.addAtom(new RangeTombstone(start, end, col.timestamp, col.localExpirationTime)); continue; } - - CellName cname = cfm.comparator.cellFromByteBuffer(col.getName()); + + assert cfm.isCQL3Table() || col.getName().hasRemaining() : "Cell name should not be empty"; + CellName cname = col.getName().hasRemaining() ? cfm.comparator.cellFromByteBuffer(col.getName()) + : cfm.comparator.rowMarker(Composites.EMPTY); if (col.isExpiring()) { http://git-wip-us.apache.org/repos/asf/cassandra/blob/8137fce5/test/resources/CQLTable.json ---------------------------------------------------------------------- diff --git a/test/resources/CQLTable.json b/test/resources/CQLTable.json new file mode 100644 index 0000000..af15f70 --- /dev/null +++ b/test/resources/CQLTable.json @@ -0,0 +1,10 @@ +[ +{"key": "00000001", + "cells": [["","",1408056347831000], + ["v1","NY",1408056347831000], + ["v2","1980",1408056347831000]]}, +{"key": "00000002", + "cells": [["","",1408056347812000], + ["v1","CA",1408056347812000], + ["v2","2014",1408056347812000]]} +] http://git-wip-us.apache.org/repos/asf/cassandra/blob/8137fce5/test/unit/org/apache/cassandra/tools/SSTableImportTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/tools/SSTableImportTest.java b/test/unit/org/apache/cassandra/tools/SSTableImportTest.java index 2fdeaf4..308a184 100644 --- a/test/unit/org/apache/cassandra/tools/SSTableImportTest.java +++ b/test/unit/org/apache/cassandra/tools/SSTableImportTest.java @@ -18,7 +18,11 @@ */ package org.apache.cassandra.tools; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.hasItem; + import static org.apache.cassandra.io.sstable.SSTableUtils.tempSSTableFile; import static org.apache.cassandra.utils.ByteBufferUtil.hexToBytes; @@ -27,16 +31,21 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import org.hamcrest.Description; +import org.hamcrest.Matcher; import org.junit.Test; +import org.junit.internal.matchers.TypeSafeMatcher; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; +import org.apache.cassandra.cql3.QueryProcessor; +import org.apache.cassandra.cql3.UntypedResultSet; +import org.apache.cassandra.cql3.UntypedResultSet.Row; import org.apache.cassandra.db.*; import org.apache.cassandra.db.columniterator.OnDiskAtomIterator; import org.apache.cassandra.db.filter.QueryFilter; import org.apache.cassandra.io.sstable.Descriptor; import org.apache.cassandra.io.sstable.SSTableReader; -import org.apache.cassandra.utils.ByteBufferUtil; public class SSTableImportTest extends SchemaLoader { @@ -138,4 +147,55 @@ public class SSTableImportTest extends SchemaLoader assert c instanceof CounterCell : c; assert ((CounterCell) c).total() == 42; } + + @Test + /* + * The schema is + * CREATE TABLE cql_keyspace.table1 (k int PRIMARY KEY, v1 text, v2 int) + * */ + public void shouldImportCqlTable() throws IOException, URISyntaxException + { + String cql_keyspace = "cql_keyspace"; + String cql_table = "table1"; + String jsonUrl = resourcePath("CQLTable.json"); + File tempSS = tempSSTableFile(cql_keyspace, cql_table); + new SSTableImport(true).importJson(jsonUrl, cql_keyspace, cql_table, tempSS.getPath()); + SSTableReader reader = SSTableReader.open(Descriptor.fromFilename(tempSS.getPath())); + Keyspace.open(cql_keyspace).getColumnFamilyStore(cql_table).addSSTable(reader); + + UntypedResultSet result = QueryProcessor.executeOnceInternal(String.format("SELECT * FROM %s.%s", cql_keyspace, cql_table)); + assertThat(result.size(), is(2)); + assertThat(result, hasItem(withElements(1, "NY", 1980))); + assertThat(result, hasItem(withElements(2, "CA", 2014))); + } + + @Test(expected=AssertionError.class) + public void shouldRejectEmptyCellNamesForNonCqlTables() throws IOException, URISyntaxException + { + String jsonUrl = resourcePath("CQLTable.json"); + File tempSS = tempSSTableFile("Keyspace1", "Counter1"); + new SSTableImport(true).importJson(jsonUrl, "Keyspace1", "Counter1", tempSS.getPath()); + } + + private static Matcher<UntypedResultSet.Row> withElements(final int key, final String v1, final int v2) { + return new TypeSafeMatcher<UntypedResultSet.Row>() + { + @Override + public boolean matchesSafely(Row input) + { + if (!input.has("k") || !input.has("v1") || !input.has("v2")) + return false; + return input.getInt("k") == key + && input.getString("v1").equals(v1) + && input.getInt("v2") == v2; + } + + @Override + public void describeTo(Description description) + { + description.appendText(String.format("a row containing: %s, %s, %s", key, v1, v2)); + } + }; + + } }