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/17 23:52:21 UTC
cassandra git commit: Fix and move dropped columns info to a separate
schema table
Repository: cassandra
Updated Branches:
refs/heads/trunk dc8523819 -> 1b5fa8ce3
Fix and move dropped columns info to a separate schema table
patch by Aleksey Yeschenko; reviewed by Tyler Hobbs for CASSANDRA-6717
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/1b5fa8ce
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/1b5fa8ce
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/1b5fa8ce
Branch: refs/heads/trunk
Commit: 1b5fa8ce3cbd238b0e735ed067eb95c83b67f262
Parents: dc85238
Author: Aleksey Yeschenko <al...@apache.org>
Authored: Sat Jul 18 00:52:40 2015 +0300
Committer: Aleksey Yeschenko <al...@apache.org>
Committed: Sat Jul 18 00:52:40 2015 +0300
----------------------------------------------------------------------
.../org/apache/cassandra/config/CFMetaData.java | 48 +++++++-
.../cql3/statements/AlterTableStatement.java | 5 +-
.../org/apache/cassandra/db/LegacyLayout.java | 15 ++-
.../cassandra/schema/LegacySchemaMigrator.java | 27 ++++-
.../apache/cassandra/schema/SchemaKeyspace.java | 115 ++++++++++++-------
.../cassandra/schema/SchemaKeyspace.java.rej | 80 -------------
.../schema/LegacySchemaMigratorTest.java | 27 +++++
7 files changed, 184 insertions(+), 133 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index 81ef217..6c53699 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.*;
@@ -1193,7 +1194,7 @@ public final class CFMetaData
public void recordColumnDrop(ColumnDefinition def)
{
- droppedColumns.put(def.name.bytes, new DroppedColumn(def.type, FBUtilities.timestampMicros()));
+ droppedColumns.put(def.name.bytes, new DroppedColumn(def.name.toString(), def.type, FBUtilities.timestampMicros()));
}
public void renameColumn(ColumnIdentifier from, ColumnIdentifier to) throws InvalidRequestException
@@ -1261,6 +1262,14 @@ public final class CFMetaData
return false;
}
+ public boolean hasDroppedCollectionColumns()
+ {
+ for (DroppedColumn def : getDroppedColumns().values())
+ if (def.type instanceof CollectionType && def.type.isMultiCell())
+ return true;
+ return false;
+ }
+
public boolean isSuper()
{
return isSuper;
@@ -1536,13 +1545,48 @@ public final class CFMetaData
public static class DroppedColumn
{
+ // we only allow dropping REGULAR columns, from CQL-native tables, so the names are always of UTF8Type
+ public final String name;
public final AbstractType<?> type;
+
+ // drop timestamp, in microseconds, yet with millisecond granularity
public final long droppedTime;
- public DroppedColumn(AbstractType<?> type, long droppedTime)
+ public DroppedColumn(String name, AbstractType<?> type, long droppedTime)
{
+ this.name = name;
this.type = type;
this.droppedTime = droppedTime;
}
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ return true;
+
+ if (!(o instanceof DroppedColumn))
+ return false;
+
+ DroppedColumn dc = (DroppedColumn) o;
+
+ return name.equals(dc.name) && type.equals(dc.type) && droppedTime == dc.droppedTime;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hashCode(name, type, droppedTime);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MoreObjects.toStringHelper(this)
+ .add("name", name)
+ .add("type", type)
+ .add("droppedTime", droppedTime)
+ .toString();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
index e0c5f4e..a247cdb 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -129,11 +129,10 @@ public class AlterTableStatement extends SchemaAlteringStatement
// some data using the old type, and so we can't allow adding a collection with the same name unless
// the types are compatible (see #6276).
CFMetaData.DroppedColumn dropped = cfm.getDroppedColumns().get(columnName.bytes);
- // We could have type == null for old dropped columns, in which case we play it safe and refuse
- if (dropped != null && (dropped.type == null || (dropped.type instanceof CollectionType && !type.isCompatibleWith(dropped.type))))
+ if (dropped != null && dropped.type instanceof CollectionType && !type.isCompatibleWith(dropped.type))
throw new InvalidRequestException(String.format("Cannot add a collection with the name %s " +
"because a collection with the same name and a different type%s has already been used in the past",
- columnName, dropped.type == null ? "" : " (" + dropped.type.asCQL3Type() + ")"));
+ columnName, " (" + dropped.type.asCQL3Type() + ')'));
}
Integer componentIndex = cfm.isCompound() ? cfm.comparator.size() : null;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/src/java/org/apache/cassandra/db/LegacyLayout.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/LegacyLayout.java b/src/java/org/apache/cassandra/db/LegacyLayout.java
index 9eb7145..f063256 100644
--- a/src/java/org/apache/cassandra/db/LegacyLayout.java
+++ b/src/java/org/apache/cassandra/db/LegacyLayout.java
@@ -41,6 +41,8 @@ import org.apache.cassandra.thrift.ColumnDef;
import org.apache.cassandra.utils.*;
import org.apache.hadoop.io.serializer.Serialization;
+import static org.apache.cassandra.utils.ByteBufferUtil.bytes;
+
/**
* Functions to deal with the old format.
*/
@@ -67,7 +69,7 @@ public abstract class LegacyLayout
return comparator.subtype(0);
}
- boolean hasCollections = metadata.hasCollectionColumns();
+ boolean hasCollections = metadata.hasCollectionColumns() || metadata.hasDroppedCollectionColumns();
List<AbstractType<?>> types = new ArrayList<>(comparator.size() + (metadata.isDense() ? 0 : 1) + (hasCollections ? 1 : 0));
types.addAll(comparator.subtypes());
@@ -75,14 +77,19 @@ public abstract class LegacyLayout
if (!metadata.isDense())
{
types.add(UTF8Type.instance);
+
if (hasCollections)
{
Map<ByteBuffer, CollectionType> defined = new HashMap<>();
+
+ for (CFMetaData.DroppedColumn def : metadata.getDroppedColumns().values())
+ if (def.type instanceof CollectionType && def.type.isMultiCell())
+ defined.put(bytes(def.name), (CollectionType) def.type);
+
for (ColumnDefinition def : metadata.partitionColumns())
- {
if (def.type instanceof CollectionType && def.type.isMultiCell())
- defined.put(def.name.bytes, (CollectionType)def.type);
- }
+ defined.put(def.name.bytes, (CollectionType) def.type);
+
types.add(ColumnToCollectionType.getInstance(defined));
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/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 159396b..879a505 100644
--- a/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java
+++ b/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java
@@ -330,7 +330,7 @@ public final class LegacySchemaMigrator
cfm.bloomFilterFpChance(cfm.getBloomFilterFpChance());
if (tableRow.has("dropped_columns"))
- addDroppedColumns(cfm, tableRow.getMap("dropped_columns", UTF8Type.instance, LongType.instance), Collections.emptyMap());
+ addDroppedColumns(cfm, rawComparator, tableRow.getMap("dropped_columns", UTF8Type.instance, LongType.instance));
cfm.triggers(createTriggersFromTriggerRows(triggerRows));
@@ -396,14 +396,33 @@ public final class LegacySchemaMigrator
return false;
}
- private static void addDroppedColumns(CFMetaData cfm, Map<String, Long> droppedTimes, Map<String, String> types)
+ /*
+ * Prior to 3.0 we used to not store the type of the dropped columns, relying on all collection info being
+ * present in the comparator, forever. That allowed us to perform certain validations in AlterTableStatement
+ * (namely not allowing to re-add incompatible collection columns, with the same name, but a different type).
+ *
+ * In 3.0, we no longer preserve the original comparator, and reconstruct it from the columns instead. That means
+ * that we should preserve the type of the dropped columns now, and, during migration, fetch the types from
+ * the original comparator if necessary.
+ */
+ private static void addDroppedColumns(CFMetaData cfm, AbstractType<?> comparator, Map<String, Long> droppedTimes)
{
+ AbstractType<?> last = comparator.getComponents().get(comparator.componentsCount() - 1);
+ Map<ByteBuffer, CollectionType> collections = last instanceof ColumnToCollectionType
+ ? ((ColumnToCollectionType) last).defined
+ : Collections.emptyMap();
+
for (Map.Entry<String, Long> entry : droppedTimes.entrySet())
{
String name = entry.getKey();
+ ByteBuffer nameBytes = UTF8Type.instance.decompose(name);
long time = entry.getValue();
- AbstractType<?> type = types.containsKey(name) ? TypeParser.parse(types.get(name)) : null;
- cfm.getDroppedColumns().put(UTF8Type.instance.decompose(name), new CFMetaData.DroppedColumn(type, time));
+
+ AbstractType<?> type = collections.containsKey(nameBytes)
+ ? collections.get(nameBytes)
+ : BytesType.instance;
+
+ cfm.getDroppedColumns().put(nameBytes, new CFMetaData.DroppedColumn(name, type, time));
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/src/java/org/apache/cassandra/schema/SchemaKeyspace.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java
index 739d8a3..4228a46 100644
--- a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java
+++ b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java
@@ -74,6 +74,7 @@ public final class SchemaKeyspace
public static final String KEYSPACES = "keyspaces";
public static final String TABLES = "tables";
public static final String COLUMNS = "columns";
+ public static final String DROPPED_COLUMNS = "dropped_columns";
public static final String TRIGGERS = "triggers";
public static final String TYPES = "types";
public static final String FUNCTIONS = "functions";
@@ -97,7 +98,6 @@ public final class SchemaKeyspace
"CREATE TABLE %s ("
+ "keyspace_name text,"
+ "table_name text,"
- + "id uuid,"
+ "bloom_filter_fp_chance double,"
+ "caching map<text, text>,"
+ "comment text,"
@@ -107,16 +107,12 @@ public final class SchemaKeyspace
+ "default_time_to_live int,"
+ "flags set<text>," // SUPER, COUNTER, DENSE, COMPOUND
+ "gc_grace_seconds int,"
+ + "id uuid,"
+ "max_index_interval int,"
+ "memtable_flush_period_in_ms int,"
+ "min_index_interval int,"
+ "read_repair_chance double,"
+ "speculative_retry text,"
-
- // TODO: move into a separate table
- + "dropped_columns map<text, bigint>,"
- + "dropped_columns_types map<text, text>,"
-
+ "PRIMARY KEY ((keyspace_name), table_name))");
private static final CFMetaData Columns =
@@ -135,6 +131,17 @@ public final class SchemaKeyspace
+ "validator text,"
+ "PRIMARY KEY ((keyspace_name), table_name, column_name))");
+ private static final CFMetaData DroppedColumns =
+ compile(DROPPED_COLUMNS,
+ "dropped column registry",
+ "CREATE TABLE %s ("
+ + "keyspace_name text,"
+ + "table_name text,"
+ + "column_name text,"
+ + "dropped_time timestamp,"
+ + "type text,"
+ + "PRIMARY KEY ((keyspace_name), table_name, column_name))");
+
private static final CFMetaData Triggers =
compile(TRIGGERS,
"trigger definitions",
@@ -186,7 +193,7 @@ public final class SchemaKeyspace
+ "PRIMARY KEY ((keyspace_name), aggregate_name, signature))");
public static final List<CFMetaData> All =
- ImmutableList.of(Keyspaces, Tables, Columns, Triggers, Types, Functions, Aggregates);
+ ImmutableList.of(Keyspaces, Tables, Columns, DroppedColumns, Triggers, Types, Functions, Aggregates);
private static CFMetaData compile(String name, String description, String schema)
{
@@ -810,27 +817,20 @@ public final class SchemaKeyspace
.map("caching", table.getCaching().asMap())
.map("compaction", buildCompactionMap(table))
.map("compression", table.compressionParameters().asMap())
- .set("flags", flagsToStrings(table.flags()));
-
- for (Map.Entry<ByteBuffer, CFMetaData.DroppedColumn> entry : table.getDroppedColumns().entrySet())
- {
- String name = UTF8Type.instance.getString(entry.getKey());
- CFMetaData.DroppedColumn column = entry.getValue();
- adder.addMapEntry("dropped_columns", name, column.droppedTime);
- if (column.type != null)
- adder.addMapEntry("dropped_columns_types", name, column.type.toString());
- }
+ .set("flags", flagsToStrings(table.flags()))
+ .build();
if (withColumnsAndTriggers)
{
for (ColumnDefinition column : table.allColumns())
addColumnToSchemaMutation(table, column, timestamp, mutation);
+ for (CFMetaData.DroppedColumn column : table.getDroppedColumns().values())
+ addDroppedColumnToSchemaMutation(table, column, timestamp, mutation);
+
for (TriggerMetadata trigger : table.getTriggers())
addTriggerToSchemaMutation(table, trigger, timestamp, mutation);
}
-
- adder.build();
}
/*
@@ -885,7 +885,7 @@ public final class SchemaKeyspace
{
// Thrift only knows about the REGULAR ColumnDefinition type, so don't consider other type
// are being deleted just because they are not here.
- if (fromThrift && column.kind != ColumnDefinition.Kind.REGULAR)
+ if (fromThrift && column.kind != ColumnDefinition.Kind.REGULAR) // TODO FIXME
continue;
dropColumnFromSchemaMutation(oldTable, column, timestamp, mutation);
@@ -899,6 +899,18 @@ public final class SchemaKeyspace
for (ByteBuffer name : columnDiff.entriesDiffering().keySet())
addColumnToSchemaMutation(newTable, newTable.getColumnDefinition(name), timestamp, mutation);
+ // dropped columns
+ MapDifference<ByteBuffer, CFMetaData.DroppedColumn> droppedColumnDiff =
+ Maps.difference(oldTable.getDroppedColumns(), newTable.getDroppedColumns());
+
+ // newly dropped columns
+ for (CFMetaData.DroppedColumn column : droppedColumnDiff.entriesOnlyOnRight().values())
+ addDroppedColumnToSchemaMutation(newTable, column, timestamp, mutation);
+
+ // columns added then dropped again
+ for (ByteBuffer name : droppedColumnDiff.entriesDiffering().keySet())
+ addDroppedColumnToSchemaMutation(newTable, newTable.getDroppedColumns().get(name), timestamp, mutation);
+
MapDifference<String, TriggerMetadata> triggerDiff = triggersDiff(oldTable.getTriggers(), newTable.getTriggers());
// dropped triggers
@@ -994,10 +1006,14 @@ public final class SchemaKeyspace
List<ColumnDefinition> columns =
readSchemaPartitionForTableAndApply(COLUMNS, keyspace, table, SchemaKeyspace::createColumnsFromColumnsPartition);
+ Map<ByteBuffer, CFMetaData.DroppedColumn> droppedColumns =
+ readSchemaPartitionForTableAndApply(DROPPED_COLUMNS, keyspace, table, SchemaKeyspace::createDroppedColumnsFromDroppedColumnsPartition);
+
Triggers triggers =
readSchemaPartitionForTableAndApply(TRIGGERS, keyspace, table, SchemaKeyspace::createTriggersFromTriggersPartition);
- return createTableFromTableRowAndColumns(row, columns).triggers(triggers);
+ return createTableFromTableRowAndColumns(row, columns).droppedColumns(droppedColumns)
+ .triggers(triggers);
}
public static CFMetaData createTableFromTableRowAndColumns(UntypedResultSet.Row row, List<ColumnDefinition> columns)
@@ -1046,14 +1062,6 @@ public final class SchemaKeyspace
.readRepairChance(row.getDouble("read_repair_chance"))
.speculativeRetry(CFMetaData.SpeculativeRetry.fromString(row.getString("speculative_retry")));
- if (row.has("dropped_columns"))
- {
- Map<String, String> types = row.has("dropped_columns_types")
- ? row.getTextMap("dropped_columns_types")
- : Collections.<String, String>emptyMap();
- addDroppedColumns(cfm, row.getMap("dropped_columns", UTF8Type.instance, LongType.instance), types);
- }
-
return cfm;
}
@@ -1073,17 +1081,6 @@ public final class SchemaKeyspace
.collect(toSet());
}
- private static void addDroppedColumns(CFMetaData cfm, Map<String, Long> droppedTimes, Map<String, String> types)
- {
- for (Map.Entry<String, Long> entry : droppedTimes.entrySet())
- {
- String name = entry.getKey();
- long time = entry.getValue();
- AbstractType<?> type = types.containsKey(name) ? TypeParser.parse(types.get(name)) : null;
- cfm.getDroppedColumns().put(UTF8Type.instance.decompose(name), new CFMetaData.DroppedColumn(type, time));
- }
- }
-
/*
* Column metadata serialization/deserialization.
*/
@@ -1146,6 +1143,44 @@ public final class SchemaKeyspace
}
/*
+ * Dropped column metadata serialization/deserialization.
+ */
+
+ private static void addDroppedColumnToSchemaMutation(CFMetaData table, CFMetaData.DroppedColumn column, long timestamp, Mutation mutation)
+ {
+ RowUpdateBuilder adder = new RowUpdateBuilder(DroppedColumns, timestamp, mutation).clustering(table.cfName, column.name);
+
+ adder.add("dropped_time", new Date(TimeUnit.MICROSECONDS.toMillis(column.droppedTime)))
+ .add("type", column.type.toString())
+ .build();
+ }
+
+ private static Map<ByteBuffer, CFMetaData.DroppedColumn> createDroppedColumnsFromDroppedColumnsPartition(RowIterator serializedColumns)
+ {
+ String query = String.format("SELECT * FROM %s.%s", NAME, DROPPED_COLUMNS);
+ Map<ByteBuffer, CFMetaData.DroppedColumn> columns = new HashMap<>();
+ for (CFMetaData.DroppedColumn column : createDroppedColumnsFromDroppedColumnRows(QueryProcessor.resultify(query, serializedColumns)))
+ columns.put(UTF8Type.instance.decompose(column.name), column);
+ return columns;
+ }
+
+ private static List<CFMetaData.DroppedColumn> createDroppedColumnsFromDroppedColumnRows(UntypedResultSet rows)
+ {
+ List<CFMetaData.DroppedColumn> columns = new ArrayList<>(rows.size());
+ rows.forEach(row -> columns.add(createDroppedColumnFromDroppedColumnRow(row)));
+ return columns;
+ }
+
+ private static CFMetaData.DroppedColumn createDroppedColumnFromDroppedColumnRow(UntypedResultSet.Row row)
+ {
+ String name = row.getString("column_name");
+ AbstractType type = TypeParser.parse(row.getString("type"));
+ long droppedTime = TimeUnit.MILLISECONDS.toMicros(row.getLong("dropped_time"));
+
+ return new CFMetaData.DroppedColumn(name, type, droppedTime);
+ }
+
+ /*
* Trigger metadata serialization/deserialization.
*/
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/src/java/org/apache/cassandra/schema/SchemaKeyspace.java.rej
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java.rej b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java.rej
deleted file mode 100644
index 460fc3a..0000000
--- a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java.rej
+++ /dev/null
@@ -1,80 +0,0 @@
-diff a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java (rejected hunks)
-@@ -1095,68 +1095,32 @@ public final class SchemaKeyspace
- .build();
- }
-
-- private static String serializeKind(ColumnDefinition.Kind kind, boolean isDense)
-- {
-- // For backward compatibility, we special case CLUSTERING_COLUMN and the case where the table is dense.
-- if (kind == ColumnDefinition.Kind.CLUSTERING_COLUMN)
-- return "clustering_key";
--
-- if (kind == ColumnDefinition.Kind.REGULAR && isDense)
-- return "compact_value";
--
-- return kind.toString().toLowerCase();
-- }
--
-- public static ColumnDefinition.Kind deserializeKind(String kind)
-- {
-- if ("clustering_key".equalsIgnoreCase(kind))
-- return ColumnDefinition.Kind.CLUSTERING_COLUMN;
-- if ("compact_value".equalsIgnoreCase(kind))
-- return ColumnDefinition.Kind.REGULAR;
-- return Enum.valueOf(ColumnDefinition.Kind.class, kind.toUpperCase());
-- }
--
- private static void dropColumnFromSchemaMutation(CFMetaData table, ColumnDefinition column, long timestamp, Mutation mutation)
- {
- // Note: we do want to use name.toString(), not name.bytes directly for backward compatibility (For CQL3, this won't make a difference).
- RowUpdateBuilder.deleteRow(Columns, timestamp, mutation, table.cfName, column.name.toString());
- }
-
-- private static List<ColumnDefinition> createColumnsFromColumnRows(UntypedResultSet rows,
-- String keyspace,
-- String table,
-- AbstractType<?> rawComparator,
-- AbstractType<?> rawSubComparator,
-- boolean isSuper,
-- boolean isCQLTable)
-+ private static List<ColumnDefinition> createColumnsFromColumnRows(UntypedResultSet rows)
- {
-- List<ColumnDefinition> columns = new ArrayList<>();
-- for (UntypedResultSet.Row row : rows)
-- columns.add(createColumnFromColumnRow(row, keyspace, table, rawComparator, rawSubComparator, isSuper, isCQLTable));
-+ List<ColumnDefinition> columns = new ArrayList<>(rows.size());
-+ rows.forEach(row -> columns.add(createColumnFromColumnRow(row)));
- return columns;
- }
-
-- private static ColumnDefinition createColumnFromColumnRow(UntypedResultSet.Row row,
-- String keyspace,
-- String table,
-- AbstractType<?> rawComparator,
-- AbstractType<?> rawSubComparator,
-- boolean isSuper,
-- boolean isCQLTable)
-+ private static ColumnDefinition createColumnFromColumnRow(UntypedResultSet.Row row)
- {
-- ColumnDefinition.Kind kind = deserializeKind(row.getString("type"));
-+ String keyspace = row.getString("keyspace_name");
-+ String table = row.getString("table_name");
-+
-+ ColumnIdentifier name = ColumnIdentifier.getInterned(row.getBytes("column_name_bytes"), row.getString("column_name"));
-+
-+ ColumnDefinition.Kind kind = ColumnDefinition.Kind.valueOf(row.getString("type").toUpperCase());
-
- Integer componentIndex = null;
- if (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;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1b5fa8ce/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 659b6c6..eb5e5f5 100644
--- a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
+++ b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java
@@ -241,6 +241,7 @@ public class LegacySchemaMigratorTest
+ "PRIMARY KEY((bar, baz), qux, quz) ) "
+ "WITH COMPACT STORAGE", ks_cql))));
+ keyspaces.add(keyspaceWithDroppedCollections());
keyspaces.add(keyspaceWithTriggers());
keyspaces.add(keyspaceWithUDTs());
keyspaces.add(keyspaceWithUDFs());
@@ -249,6 +250,32 @@ public class LegacySchemaMigratorTest
return keyspaces;
}
+ private static KeyspaceMetadata keyspaceWithDroppedCollections()
+ {
+ String keyspace = KEYSPACE_PREFIX + "DroppedCollections";
+
+ CFMetaData table =
+ CFMetaData.compile("CREATE TABLE dropped_columns ("
+ + "foo text,"
+ + "bar text,"
+ + "map1 map<text, text>,"
+ + "map2 map<int, int>,"
+ + "set1 set<ascii>,"
+ + "list1 list<blob>,"
+ + "PRIMARY KEY ((foo), bar))",
+ keyspace);
+
+ String[] collectionColumnNames = { "map1", "map2", "set1", "list1" };
+ for (String name : collectionColumnNames)
+ {
+ ColumnDefinition column = table.getColumnDefinition(bytes(name));
+ table.recordColumnDrop(column);
+ table.removeColumnDefinition(column);
+ }
+
+ return KeyspaceMetadata.create(keyspace, KeyspaceParams.simple(1), Tables.of(table));
+ }
+
private static KeyspaceMetadata keyspaceWithTriggers()
{
String keyspace = KEYSPACE_PREFIX + "Triggers";