You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2015/07/23 17:43:31 UTC
cassandra git commit: Fix migration of pk-only compact storage tables
Repository: cassandra
Updated Branches:
refs/heads/trunk d9dfbddbe -> 2d55c1e84
Fix migration of pk-only compact storage tables
patch by Aleksey Yeschenko; reviewed by Sylvain Lebresne for
CASSANDRA-9874
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/2d55c1e8
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/2d55c1e8
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/2d55c1e8
Branch: refs/heads/trunk
Commit: 2d55c1e8465015fd18cc71a1228489aaf5c6eea8
Parents: d9dfbdd
Author: Aleksey Yeschenko <al...@apache.org>
Authored: Thu Jul 23 16:06:02 2015 +0300
Committer: Aleksey Yeschenko <al...@apache.org>
Committed: Thu Jul 23 18:44:47 2015 +0300
----------------------------------------------------------------------
CHANGES.txt | 2 +-
.../cassandra/schema/LegacySchemaMigrator.java | 131 ++++++++++++-------
.../schema/LegacySchemaMigratorTest.java | 15 ++-
3 files changed, 95 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2d55c1e8/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index d405a4d..7f061c1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,7 +4,7 @@
* Change CREATE/ALTER TABLE syntax for compression (CASSANDRA-8384)
* Cleanup crc and adler code for java 8 (CASSANDRA-9650)
* Storage engine refactor (CASSANDRA-8099, 9743, 9746, 9759, 9781, 9808, 9825, 9848,
- 9705, 9859, 9867)
+ 9705, 9859, 9867, 9874)
* Update Guava to 18.0 (CASSANDRA-9653)
* Bloom filter false positive ratio is not honoured (CASSANDRA-8413)
* New option for cassandra-stress to leave a ratio of columns null (CASSANDRA-9522)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2d55c1e8/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java b/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java
index f554ffb..7326fa9 100644
--- a/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java
+++ b/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java
@@ -296,7 +296,16 @@ public final class LegacySchemaMigrator
needsUpgrade);
if (needsUpgrade)
- addDefinitionForUpgrade(columnDefs, ksName, cfName, isStaticCompactTable, isSuper, rawComparator, subComparator, defaultValidator);
+ {
+ addDefinitionForUpgrade(columnDefs,
+ ksName,
+ cfName,
+ isStaticCompactTable,
+ isSuper,
+ rawComparator,
+ subComparator,
+ defaultValidator);
+ }
CFMetaData cfm = CFMetaData.create(ksName, cfName, cfId, isDense, isCompound, isSuper, isCounter, columnDefs);
@@ -355,7 +364,33 @@ public final class LegacySchemaMigrator
return !hasKind(defs, ColumnDefinition.Kind.STATIC);
// For dense compact tables, we need to upgrade if we don't have a compact value definition
- return !hasKind(defs, ColumnDefinition.Kind.REGULAR);
+ return !hasRegularColumns(defs);
+ }
+
+ private static boolean hasRegularColumns(UntypedResultSet columnRows)
+ {
+ for (UntypedResultSet.Row row : columnRows)
+ {
+ /*
+ * We need to special case and ignore the empty compact column (pre-3.0, COMPACT STORAGE, primary-key only tables),
+ * since deserializeKind() will otherwise just return a REGULAR.
+ * We want the proper EmptyType regular column to be added by addDefinitionForUpgrade(), so we need
+ * checkNeedsUpgrade() to return true in this case.
+ * See CASSANDRA-9874.
+ */
+ if (isEmptyCompactValueColumn(row))
+ return false;
+
+ if (deserializeKind(row.getString("type")) == ColumnDefinition.Kind.REGULAR)
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isEmptyCompactValueColumn(UntypedResultSet.Row row)
+ {
+ return "compact_value".equals(row.getString("type")) && row.getString("column_name").isEmpty();
}
private static void addDefinitionForUpgrade(List<ColumnDefinition> defs,
@@ -389,10 +424,9 @@ public final class LegacySchemaMigrator
private static boolean hasKind(UntypedResultSet defs, ColumnDefinition.Kind kind)
{
for (UntypedResultSet.Row row : defs)
- {
if (deserializeKind(row.getString("type")) == kind)
return true;
- }
+
return false;
}
@@ -437,62 +471,59 @@ public final class LegacySchemaMigrator
boolean needsUpgrade)
{
List<ColumnDefinition> columns = new ArrayList<>();
- for (UntypedResultSet.Row row : rows)
- columns.add(createColumnFromColumnRow(row, keyspace, table, rawComparator, rawSubComparator, isSuper, isCQLTable, isStaticCompactTable, needsUpgrade));
- return columns;
- }
-
- private static ColumnDefinition createColumnFromColumnRow(UntypedResultSet.Row row,
- String keyspace,
- String table,
- AbstractType<?> rawComparator,
- AbstractType<?> rawSubComparator,
- boolean isSuper,
- boolean isCQLTable,
- boolean isStaticCompactTable,
- boolean needsUpgrade)
- {
- ColumnDefinition.Kind kind = deserializeKind(row.getString("type"));
- if (needsUpgrade && isStaticCompactTable && kind == ColumnDefinition.Kind.REGULAR)
- kind = ColumnDefinition.Kind.STATIC;
-
- Integer componentIndex = null;
- // Note that the component_index is not useful for non-primary key parts (it never really in fact since there is
- // no particular ordering of non-PK columns, we only used to use it as a simplification but that's not needed
- // anymore)
- if (kind.isPrimaryKeyKind() && row.has("component_index"))
- componentIndex = row.getInt("component_index");
-
- // Note: we save the column name as string, but we should not assume that it is an UTF8 name, we
- // we need to use the comparator fromString method
- AbstractType<?> comparator = isCQLTable
- ? UTF8Type.instance
- : CompactTables.columnDefinitionComparator(kind, isSuper, rawComparator, rawSubComparator);
- ColumnIdentifier name = ColumnIdentifier.getInterned(comparator.fromString(row.getString("column_name")), comparator);
-
- AbstractType<?> validator = parseType(row.getString("validator"));
- IndexType indexType = null;
- if (row.has("index_type"))
- indexType = IndexType.valueOf(row.getString("index_type"));
-
- Map<String, String> indexOptions = null;
- if (row.has("index_options"))
- indexOptions = fromJsonMap(row.getString("index_options"));
-
- String indexName = null;
- if (row.has("index_name"))
- indexName = row.getString("index_name");
+ for (UntypedResultSet.Row row : rows)
+ {
+ // Skip the empty compact value column. Make addDefinitionForUpgrade() re-add the proper REGULAR one.
+ if (isEmptyCompactValueColumn(row))
+ continue;
+
+ ColumnDefinition.Kind kind = deserializeKind(row.getString("type"));
+ if (needsUpgrade && isStaticCompactTable && kind == ColumnDefinition.Kind.REGULAR)
+ kind = ColumnDefinition.Kind.STATIC;
+
+ Integer componentIndex = null;
+ // Note that the component_index is not useful for non-primary key parts (it never really in fact since there is
+ // no particular ordering of non-PK columns, we only used to use it as a simplification but that's not needed
+ // anymore)
+ if (kind.isPrimaryKeyKind() && row.has("component_index"))
+ componentIndex = row.getInt("component_index");
+
+ // Note: we save the column name as string, but we should not assume that it is an UTF8 name, we
+ // we need to use the comparator fromString method
+ AbstractType<?> comparator = isCQLTable
+ ? UTF8Type.instance
+ : CompactTables.columnDefinitionComparator(kind, isSuper, rawComparator, rawSubComparator);
+ ColumnIdentifier name = ColumnIdentifier.getInterned(comparator.fromString(row.getString("column_name")), comparator);
+
+ AbstractType<?> validator = parseType(row.getString("validator"));
+
+ IndexType indexType = null;
+ if (row.has("index_type"))
+ indexType = IndexType.valueOf(row.getString("index_type"));
+
+ Map<String, String> indexOptions = null;
+ if (row.has("index_options"))
+ indexOptions = fromJsonMap(row.getString("index_options"));
+
+ String indexName = null;
+ if (row.has("index_name"))
+ indexName = row.getString("index_name");
+
+ columns.add(new ColumnDefinition(keyspace, table, name, validator, indexType, indexOptions, indexName, componentIndex, kind));
+ }
- return new ColumnDefinition(keyspace, table, name, validator, indexType, indexOptions, indexName, componentIndex, kind);
+ return columns;
}
private static ColumnDefinition.Kind deserializeKind(String kind)
{
if ("clustering_key".equalsIgnoreCase(kind))
return ColumnDefinition.Kind.CLUSTERING;
+
if ("compact_value".equalsIgnoreCase(kind))
return ColumnDefinition.Kind.REGULAR;
+
return Enum.valueOf(ColumnDefinition.Kind.class, kind.toUpperCase());
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2d55c1e8/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
index eb5e5f5..82922e6 100644
--- a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
+++ b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
@@ -232,6 +232,13 @@ public class LegacySchemaMigratorTest
+ "PRIMARY KEY(bar, baz) ) "
+ "WITH COMPACT STORAGE", ks_cql),
+ CFMetaData.compile("CREATE TABLE compact_pkonly ("
+ + "k int, "
+ + "c int, "
+ + "PRIMARY KEY (k, c)) "
+ + "WITH COMPACT STORAGE",
+ ks_cql),
+
CFMetaData.compile("CREATE TABLE foofoo ("
+ "bar text, "
+ "baz text, "
@@ -459,8 +466,12 @@ public class LegacySchemaMigratorTest
private static void addColumnToSchemaMutation(CFMetaData table, ColumnDefinition column, long timestamp, Mutation mutation)
{
- RowUpdateBuilder adder = new RowUpdateBuilder(SystemKeyspace.LegacyColumns, timestamp, mutation)
- .clustering(table.cfName, column.name.toString());
+ // We need to special case pk-only dense tables. See CASSANDRA-9874.
+ String name = table.isDense() && column.kind == ColumnDefinition.Kind.REGULAR && column.type instanceof EmptyType
+ ? ""
+ : column.name.toString();
+
+ RowUpdateBuilder adder = new RowUpdateBuilder(SystemKeyspace.LegacyColumns, timestamp, mutation).clustering(table.cfName, name);
adder.add("validator", column.type.toString())
.add("type", serializeKind(column.kind, table.isDense()))