Merge branch 'cassandra-3.0' into trunk

This commit is contained in:
Sam Tunnicliffe 2015-09-11 18:04:21 +01:00
commit 8607900454
12 changed files with 94 additions and 97 deletions

View File

@ -1273,8 +1273,8 @@ public final class CFMetaData
for (int i = 0; i < partitionKeys.size(); i++)
{
Pair<ColumnIdentifier, AbstractType> p = partitionKeys.get(i);
Integer componentIndex = partitionKeys.size() == 1 ? null : i;
partitions.add(new ColumnDefinition(keyspace, table, p.left, p.right, componentIndex, ColumnDefinition.Kind.PARTITION_KEY));
int position = partitionKeys.size() == 1 ? ColumnDefinition.NO_POSITION : i;
partitions.add(new ColumnDefinition(keyspace, table, p.left, p.right, position, ColumnDefinition.Kind.PARTITION_KEY));
}
for (int i = 0; i < clusteringColumns.size(); i++)
@ -1283,17 +1283,11 @@ public final class CFMetaData
clusterings.add(new ColumnDefinition(keyspace, table, p.left, p.right, i, ColumnDefinition.Kind.CLUSTERING));
}
for (int i = 0; i < regularColumns.size(); i++)
{
Pair<ColumnIdentifier, AbstractType> p = regularColumns.get(i);
builder.add(new ColumnDefinition(keyspace, table, p.left, p.right, null, ColumnDefinition.Kind.REGULAR));
}
for (Pair<ColumnIdentifier, AbstractType> p : regularColumns)
builder.add(new ColumnDefinition(keyspace, table, p.left, p.right, ColumnDefinition.NO_POSITION, ColumnDefinition.Kind.REGULAR));
for (int i = 0; i < staticColumns.size(); i++)
{
Pair<ColumnIdentifier, AbstractType> p = staticColumns.get(i);
builder.add(new ColumnDefinition(keyspace, table, p.left, p.right, null, ColumnDefinition.Kind.STATIC));
}
for (Pair<ColumnIdentifier, AbstractType> p : staticColumns)
builder.add(new ColumnDefinition(keyspace, table, p.left, p.right, ColumnDefinition.NO_POSITION, ColumnDefinition.Kind.STATIC));
return new CFMetaData(keyspace,
table,

View File

@ -32,7 +32,10 @@ import org.apache.cassandra.serializers.MarshalException;
public class ColumnDefinition extends ColumnSpecification implements Comparable<ColumnDefinition>
{
public static final Comparator<Object> asymmetricColumnDataComparator = (a, b) -> ((ColumnData) a).column().compareTo((ColumnDefinition) b);
public static final Comparator<Object> asymmetricColumnDataComparator =
(a, b) -> ((ColumnData) a).column().compareTo((ColumnDefinition) b);
public static final int NO_POSITION = -1;
/*
* The type of CQL3 column this definition represents.
@ -41,7 +44,7 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
* static ones.
*
* Note that thrift only knows about definitions of type REGULAR (and
* the ones whose componentIndex == null).
* the ones whose position == NO_POSITION (-1)).
*/
public enum Kind
{
@ -61,10 +64,10 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
/*
* If the column comparator is a composite type, indicates to which
* component this definition refers to. If null, the definition refers to
* component this definition refers to. If NO_POSITION (-1), the definition refers to
* the full column name.
*/
private final Integer componentIndex;
private final int position;
private final Comparator<CellPath> cellPathComparator;
private final Comparator<Object> asymmetricCellPathComparator;
@ -81,48 +84,48 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
return (kind.ordinal() << 28) | (isComplex ? 1 << 27 : 0) | position;
}
public static ColumnDefinition partitionKeyDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> validator, Integer componentIndex)
public static ColumnDefinition partitionKeyDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> type, int position)
{
return new ColumnDefinition(cfm, name, validator, componentIndex, Kind.PARTITION_KEY);
return new ColumnDefinition(cfm, name, type, position, Kind.PARTITION_KEY);
}
public static ColumnDefinition partitionKeyDef(String ksName, String cfName, String name, AbstractType<?> validator, Integer componentIndex)
public static ColumnDefinition partitionKeyDef(String ksName, String cfName, String name, AbstractType<?> type, int position)
{
return new ColumnDefinition(ksName, cfName, ColumnIdentifier.getInterned(name, true), validator, componentIndex, Kind.PARTITION_KEY);
return new ColumnDefinition(ksName, cfName, ColumnIdentifier.getInterned(name, true), type, position, Kind.PARTITION_KEY);
}
public static ColumnDefinition clusteringKeyDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> validator, Integer componentIndex)
public static ColumnDefinition clusteringDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> type, int position)
{
return new ColumnDefinition(cfm, name, validator, componentIndex, Kind.CLUSTERING);
return new ColumnDefinition(cfm, name, type, position, Kind.CLUSTERING);
}
public static ColumnDefinition clusteringKeyDef(String ksName, String cfName, String name, AbstractType<?> validator, Integer componentIndex)
public static ColumnDefinition clusteringDef(String ksName, String cfName, String name, AbstractType<?> type, int position)
{
return new ColumnDefinition(ksName, cfName, ColumnIdentifier.getInterned(name, true), validator, componentIndex, Kind.CLUSTERING);
return new ColumnDefinition(ksName, cfName, ColumnIdentifier.getInterned(name, true), type, position, Kind.CLUSTERING);
}
public static ColumnDefinition regularDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> validator)
public static ColumnDefinition regularDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> type)
{
return new ColumnDefinition(cfm, name, validator, null, Kind.REGULAR);
return new ColumnDefinition(cfm, name, type, NO_POSITION, Kind.REGULAR);
}
public static ColumnDefinition regularDef(String ksName, String cfName, String name, AbstractType<?> validator)
public static ColumnDefinition regularDef(String ksName, String cfName, String name, AbstractType<?> type)
{
return new ColumnDefinition(ksName, cfName, ColumnIdentifier.getInterned(name, true), validator, null, Kind.REGULAR);
return new ColumnDefinition(ksName, cfName, ColumnIdentifier.getInterned(name, true), type, NO_POSITION, Kind.REGULAR);
}
public static ColumnDefinition staticDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> validator)
public static ColumnDefinition staticDef(CFMetaData cfm, ByteBuffer name, AbstractType<?> type)
{
return new ColumnDefinition(cfm, name, validator, null, Kind.STATIC);
return new ColumnDefinition(cfm, name, type, NO_POSITION, Kind.STATIC);
}
public ColumnDefinition(CFMetaData cfm, ByteBuffer name, AbstractType<?> validator, Integer componentIndex, Kind kind)
public ColumnDefinition(CFMetaData cfm, ByteBuffer name, AbstractType<?> type, int position, Kind kind)
{
this(cfm.ksName,
cfm.cfName,
ColumnIdentifier.getInterned(name, cfm.getColumnDefinitionNameComparator(kind)),
validator,
componentIndex,
type,
position,
kind);
}
@ -130,29 +133,30 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
public ColumnDefinition(String ksName,
String cfName,
ColumnIdentifier name,
AbstractType<?> validator,
Integer componentIndex,
AbstractType<?> type,
int position,
Kind kind)
{
super(ksName, cfName, name, validator);
assert name != null && validator != null && kind != null;
super(ksName, cfName, name, type);
assert name != null && type != null && kind != null;
assert name.isInterned();
assert componentIndex == null || kind.isPrimaryKeyKind(); // The componentIndex really only make sense for partition and clustering columns,
// so make sure we don't sneak it for something else since it'd breaks equals()
assert position == NO_POSITION || kind.isPrimaryKeyKind(); // The position really only make sense for partition and clustering columns,
// so make sure we don't sneak it for something else since it'd breaks equals()
this.kind = kind;
this.componentIndex = componentIndex;
this.cellPathComparator = makeCellPathComparator(kind, validator);
this.position = position;
this.cellPathComparator = makeCellPathComparator(kind, type);
this.cellComparator = cellPathComparator == null ? ColumnData.comparator : (a, b) -> cellPathComparator.compare(a.path(), b.path());
this.asymmetricCellPathComparator = cellPathComparator == null ? null : (a, b) -> cellPathComparator.compare(((Cell)a).path(), (CellPath) b);
this.comparisonOrder = comparisonOrder(kind, isComplex(), position());
}
private static Comparator<CellPath> makeCellPathComparator(Kind kind, AbstractType<?> validator)
private static Comparator<CellPath> makeCellPathComparator(Kind kind, AbstractType<?> type)
{
if (kind.isPrimaryKeyKind() || !validator.isCollection() || !validator.isMultiCell())
if (kind.isPrimaryKeyKind() || !type.isCollection() || !type.isMultiCell())
return null;
final CollectionType type = (CollectionType)validator;
CollectionType collection = (CollectionType) type;
return new Comparator<CellPath>()
{
public int compare(CellPath path1, CellPath path2)
@ -168,29 +172,29 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
// This will get more complicated once we have non-frozen UDT and nested collections
assert path1.size() == 1 && path2.size() == 1;
return type.nameComparator().compare(path1.get(0), path2.get(0));
return collection.nameComparator().compare(path1.get(0), path2.get(0));
}
};
}
public ColumnDefinition copy()
{
return new ColumnDefinition(ksName, cfName, name, type, componentIndex, kind);
return new ColumnDefinition(ksName, cfName, name, type, position, kind);
}
public ColumnDefinition withNewName(ColumnIdentifier newName)
{
return new ColumnDefinition(ksName, cfName, newName, type, componentIndex, kind);
return new ColumnDefinition(ksName, cfName, newName, type, position, kind);
}
public ColumnDefinition withNewType(AbstractType<?> newType)
{
return new ColumnDefinition(ksName, cfName, name, newType, componentIndex, kind);
return new ColumnDefinition(ksName, cfName, name, newType, position, kind);
}
public boolean isOnAllComponents()
{
return componentIndex == null;
return position == NO_POSITION;
}
public boolean isPartitionKey()
@ -213,12 +217,13 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
return kind == Kind.REGULAR;
}
// The componentIndex. This never return null however for convenience sake:
// if componentIndex == null, this return 0. So caller should first check
// isOnAllComponents() to distinguish if that's a possibility.
/**
* For convenience sake, if position == NO_POSITION, this method will return 0. The callers should first check
* isOnAllComponents() to distinguish between proper 0 position and NO_POSITION.
*/
public int position()
{
return componentIndex == null ? 0 : componentIndex;
return Math.max(0, position);
}
@Override
@ -237,13 +242,13 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
&& Objects.equal(name, cd.name)
&& Objects.equal(type, cd.type)
&& Objects.equal(kind, cd.kind)
&& Objects.equal(componentIndex, cd.componentIndex);
&& Objects.equal(position, cd.position);
}
@Override
public int hashCode()
{
return Objects.hashCode(ksName, cfName, name, type, kind, componentIndex);
return Objects.hashCode(ksName, cfName, name, type, kind, position);
}
@Override
@ -253,7 +258,7 @@ public class ColumnDefinition extends ColumnSpecification implements Comparable<
.add("name", name)
.add("type", type)
.add("kind", kind)
.add("componentIndex", componentIndex)
.add("position", position)
.toString();
}

View File

@ -50,8 +50,13 @@ public class Columns extends AbstractCollection<ColumnDefinition> implements Col
{
public static final Serializer serializer = new Serializer();
public static final Columns NONE = new Columns(BTree.empty(), 0);
public static final ColumnDefinition FIRST_COMPLEX = new ColumnDefinition("", "", ColumnIdentifier.getInterned(ByteBufferUtil.EMPTY_BYTE_BUFFER, UTF8Type.instance),
SetType.getInstance(UTF8Type.instance, true), null, ColumnDefinition.Kind.REGULAR);
public static final ColumnDefinition FIRST_COMPLEX =
new ColumnDefinition("",
"",
ColumnIdentifier.getInterned(ByteBufferUtil.EMPTY_BYTE_BUFFER, UTF8Type.instance),
SetType.getInstance(UTF8Type.instance, true),
ColumnDefinition.NO_POSITION,
ColumnDefinition.Kind.REGULAR);
private final Object[] columns;
private final int complexIdx; // Index of the first complex column

View File

@ -476,7 +476,7 @@ public final class LegacySchemaMigrator
}
else if (isStaticCompactTable)
{
defs.add(ColumnDefinition.clusteringKeyDef(ksName, cfName, names.defaultClusteringName(), rawComparator, null));
defs.add(ColumnDefinition.clusteringDef(ksName, cfName, names.defaultClusteringName(), rawComparator, ColumnDefinition.NO_POSITION));
defs.add(ColumnDefinition.regularDef(ksName, cfName, names.defaultCompactValueName(), defaultValidator));
}
else
@ -572,7 +572,7 @@ public final class LegacySchemaMigrator
if (needsUpgrade && isStaticCompactTable && kind == ColumnDefinition.Kind.REGULAR)
kind = ColumnDefinition.Kind.STATIC;
Integer componentIndex = null;
int componentIndex = ColumnDefinition.NO_POSITION;
// 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)

View File

@ -118,9 +118,9 @@ public final class SchemaKeyspace
+ "table_name text,"
+ "column_name text,"
+ "column_name_bytes blob,"
+ "component_index int,"
+ "kind text,"
+ "position int,"
+ "type text,"
+ "validator text,"
+ "PRIMARY KEY ((keyspace_name), table_name, column_name))");
private static final CFMetaData DroppedColumns =
@ -141,7 +141,7 @@ public final class SchemaKeyspace
+ "keyspace_name text,"
+ "table_name text,"
+ "trigger_name text,"
+ "trigger_options frozen<map<text, text>>,"
+ "options frozen<map<text, text>>,"
+ "PRIMARY KEY ((keyspace_name), table_name, trigger_name))");
private static final CFMetaData MaterializedViews =
@ -1162,9 +1162,9 @@ public final class SchemaKeyspace
RowUpdateBuilder adder = new RowUpdateBuilder(Columns, timestamp, mutation).clustering(table.cfName, column.name.toString());
adder.add("column_name_bytes", column.name.bytes)
.add("validator", column.type.toString())
.add("type", column.kind.toString().toLowerCase())
.add("component_index", column.isOnAllComponents() ? null : column.position())
.add("kind", column.kind.toString().toLowerCase())
.add("position", column.isOnAllComponents() ? ColumnDefinition.NO_POSITION : column.position())
.add("type", column.type.toString())
.build();
}
@ -1188,15 +1188,13 @@ public final class SchemaKeyspace
ColumnIdentifier name = ColumnIdentifier.getInterned(row.getBytes("column_name_bytes"), row.getString("column_name"));
ColumnDefinition.Kind kind = ColumnDefinition.Kind.valueOf(row.getString("type").toUpperCase());
ColumnDefinition.Kind kind = ColumnDefinition.Kind.valueOf(row.getString("kind").toUpperCase());
Integer componentIndex = null;
if (row.has("component_index"))
componentIndex = row.getInt("component_index");
int position = row.getInt("position");
AbstractType<?> validator = parseType(row.getString("validator"));
AbstractType<?> type = parseType(row.getString("type"));
return new ColumnDefinition(keyspace, table, name, validator, componentIndex, kind);
return new ColumnDefinition(keyspace, table, name, type, position, kind);
}
/*
@ -1245,7 +1243,7 @@ public final class SchemaKeyspace
{
new RowUpdateBuilder(Triggers, timestamp, mutation)
.clustering(table.cfName, trigger.name)
.frozenMap("trigger_options", Collections.singletonMap("class", trigger.classOption))
.frozenMap("options", Collections.singletonMap("class", trigger.classOption))
.build();
}
@ -1271,7 +1269,7 @@ public final class SchemaKeyspace
private static TriggerMetadata createTriggerFromTriggerRow(UntypedResultSet.Row row)
{
String name = row.getString("trigger_name");
String classOption = row.getFrozenTextMap("trigger_options").get("class");
String classOption = row.getFrozenTextMap("options").get("class");
return new TriggerMetadata(name, classOption);
}

View File

@ -238,7 +238,7 @@ public class ThriftConversion
// historical reasons)
boolean hasKeyAlias = cf_def.isSetKey_alias() && keyValidator != null && !(keyValidator instanceof CompositeType);
if (hasKeyAlias)
defs.add(ColumnDefinition.partitionKeyDef(cf_def.keyspace, cf_def.name, UTF8Type.instance.getString(cf_def.key_alias), keyValidator, null));
defs.add(ColumnDefinition.partitionKeyDef(cf_def.keyspace, cf_def.name, UTF8Type.instance.getString(cf_def.key_alias), keyValidator, ColumnDefinition.NO_POSITION));
// Now add any CQL metadata that we want to copy, skipping the keyAlias if there was one
for (ColumnDefinition def : previousCQLMetadata)
@ -376,14 +376,14 @@ public class ThriftConversion
}
else
{
defs.add(ColumnDefinition.partitionKeyDef(ks, cf, names.defaultPartitionKeyName(), keyValidator, null));
defs.add(ColumnDefinition.partitionKeyDef(ks, cf, names.defaultPartitionKeyName(), keyValidator, ColumnDefinition.NO_POSITION));
}
}
if (subComparator != null)
{
// SuperColumn tables: we use a special map to hold dynamic values within a given super column
defs.add(ColumnDefinition.clusteringKeyDef(ks, cf, names.defaultClusteringName(), comparator, 0));
defs.add(ColumnDefinition.clusteringDef(ks, cf, names.defaultClusteringName(), comparator, 0));
defs.add(ColumnDefinition.regularDef(ks, cf, CompactTables.SUPER_COLUMN_MAP_COLUMN_STR, MapType.getInstance(subComparator, defaultValidator, true)));
}
else
@ -393,7 +393,7 @@ public class ThriftConversion
: Collections.<AbstractType<?>>singletonList(comparator);
for (int i = 0; i < subTypes.size(); i++)
defs.add(ColumnDefinition.clusteringKeyDef(ks, cf, names.defaultClusteringName(), subTypes.get(i), i));
defs.add(ColumnDefinition.clusteringDef(ks, cf, names.defaultClusteringName(), subTypes.get(i), i));
defs.add(ColumnDefinition.regularDef(ks, cf, names.defaultCompactValueName(), defaultValidator));
}
@ -505,7 +505,7 @@ public class ThriftConversion
cfName,
ColumnIdentifier.getInterned(ByteBufferUtil.clone(thriftColumnDef.name), comparator),
TypeParser.parse(thriftColumnDef.validation_class),
null,
ColumnDefinition.NO_POSITION,
kind);
}

View File

@ -149,15 +149,9 @@ public class NativeSSTableLoaderClient extends SSTableLoader.Client
private static ColumnDefinition createDefinitionFromRow(Row row, String keyspace, String table)
{
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.isNull("component_index"))
componentIndex = row.getInt("component_index");
AbstractType<?> validator = TypeParser.parse(row.getString("validator"));
return new ColumnDefinition(keyspace, table, name, validator, componentIndex, kind);
AbstractType<?> type = TypeParser.parse(row.getString("type"));
int position = row.getInt("position");
ColumnDefinition.Kind kind = ColumnDefinition.Kind.valueOf(row.getString("kind").toUpperCase());
return new ColumnDefinition(keyspace, table, name, type, position, kind);
}
}

View File

@ -270,7 +270,7 @@ public class SchemaLoader
cfName,
ColumnIdentifier.getInterned(IntegerType.instance.fromString("42"), IntegerType.instance),
UTF8Type.instance,
null,
ColumnDefinition.NO_POSITION,
ColumnDefinition.Kind.REGULAR);
}
@ -280,7 +280,7 @@ public class SchemaLoader
cfName,
ColumnIdentifier.getInterned("fortytwo", true),
UTF8Type.instance,
null,
ColumnDefinition.NO_POSITION,
ColumnDefinition.Kind.REGULAR);
}

View File

@ -37,13 +37,14 @@ import org.apache.cassandra.db.marshal.SetType;
import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.io.util.DataInputBuffer;
import org.apache.cassandra.io.util.DataOutputBuffer;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.btree.BTreeSet;
import static org.apache.cassandra.utils.ByteBufferUtil.bytes;
public class ColumnsTest
{
private static CFMetaData cfMetaData = MockSchema.newCFS().metadata;
private static final CFMetaData cfMetaData = MockSchema.newCFS().metadata;
// this tests most of our functionality, since each subset we perform
// reasonably comprehensive tests of basic functionality against
@ -380,26 +381,26 @@ public class ColumnsTest
private static void addPartition(List<String> names, List<ColumnDefinition> results)
{
for (String name : names)
results.add(new ColumnDefinition(cfMetaData, ByteBufferUtil.bytes(name), UTF8Type.instance, null, ColumnDefinition.Kind.PARTITION_KEY));
results.add(ColumnDefinition.partitionKeyDef(cfMetaData, bytes(name), UTF8Type.instance, ColumnDefinition.NO_POSITION));
}
private static void addClustering(List<String> names, List<ColumnDefinition> results)
{
int i = 0;
for (String name : names)
results.add(new ColumnDefinition(cfMetaData, ByteBufferUtil.bytes(name), UTF8Type.instance, i++, ColumnDefinition.Kind.CLUSTERING));
results.add(ColumnDefinition.clusteringDef(cfMetaData, bytes(name), UTF8Type.instance, i++));
}
private static void addRegular(List<String> names, List<ColumnDefinition> results)
{
for (String name : names)
results.add(new ColumnDefinition(cfMetaData, ByteBufferUtil.bytes(name), UTF8Type.instance, null, ColumnDefinition.Kind.REGULAR));
results.add(ColumnDefinition.regularDef(cfMetaData, bytes(name), UTF8Type.instance));
}
private static <V> void addComplex(List<String> names, List<ColumnDefinition> results)
{
for (String name : names)
results.add(new ColumnDefinition(cfMetaData, ByteBufferUtil.bytes(name), SetType.getInstance(UTF8Type.instance, true), null, ColumnDefinition.Kind.REGULAR));
results.add(ColumnDefinition.regularDef(cfMetaData, bytes(name), SetType.getInstance(UTF8Type.instance, true)));
}
private static CFMetaData mock(Columns columns)