use of org.apache.cassandra.db.marshal.AbstractType in project cassandra by apache.
the class SSTableHeaderFix method processSSTable.
private void processSSTable(Descriptor desc) {
if (desc.cfname.indexOf('.') != -1) {
// no static columns, no regular columns
return;
}
TableMetadata tableMetadata = schemaCallback.apply(desc);
if (tableMetadata == null) {
error("Table %s.%s not found in the schema - NOT checking sstable %s", desc.ksname, desc.cfname, desc);
return;
}
Set<Component> components = SSTable.discoverComponentsFor(desc);
if (components.stream().noneMatch(c -> c.type == Component.Type.STATS)) {
error("sstable %s has no -Statistics.db component.", desc);
return;
}
Map<MetadataType, MetadataComponent> metadata = readSSTableMetadata(desc);
if (metadata == null)
return;
MetadataComponent component = metadata.get(MetadataType.HEADER);
if (!(component instanceof SerializationHeader.Component)) {
error("sstable %s: Expected %s, but got %s from metadata.get(MetadataType.HEADER)", desc, SerializationHeader.Component.class.getName(), component != null ? component.getClass().getName() : "'null'");
return;
}
SerializationHeader.Component header = (SerializationHeader.Component) component;
// check partition key type
AbstractType<?> keyType = validatePartitionKey(desc, tableMetadata, header);
// check clustering columns
List<AbstractType<?>> clusteringTypes = validateClusteringColumns(desc, tableMetadata, header);
// check static and regular columns
Map<ByteBuffer, AbstractType<?>> staticColumns = validateColumns(desc, tableMetadata, header.getStaticColumns(), ColumnMetadata.Kind.STATIC);
Map<ByteBuffer, AbstractType<?>> regularColumns = validateColumns(desc, tableMetadata, header.getRegularColumns(), ColumnMetadata.Kind.REGULAR);
SerializationHeader.Component newHeader = SerializationHeader.Component.buildComponentForTools(keyType, clusteringTypes, staticColumns, regularColumns, header.getEncodingStats());
// SerializationHeader.Component has no equals(), but a "good" toString()
if (header.toString().equals(newHeader.toString()))
return;
Map<MetadataType, MetadataComponent> newMetadata = new LinkedHashMap<>(metadata);
newMetadata.put(MetadataType.HEADER, newHeader);
updates.add(Pair.create(desc, newMetadata));
}
use of org.apache.cassandra.db.marshal.AbstractType in project cassandra by apache.
the class SSTableHeaderFix method validateClusteringColumns.
private List<AbstractType<?>> validateClusteringColumns(Descriptor desc, TableMetadata tableMetadata, SerializationHeader.Component header) {
List<AbstractType<?>> headerClusteringTypes = header.getClusteringTypes();
List<AbstractType<?>> clusteringTypes = new ArrayList<>();
boolean clusteringMismatch = false;
List<ColumnMetadata> schemaClustering = tableMetadata.clusteringColumns();
if (schemaClustering.size() != headerClusteringTypes.size()) {
clusteringMismatch = true;
// Just use the original types. Since the number of clustering columns don't match, there's nothing to
// meaningfully validate against.
clusteringTypes.addAll(headerClusteringTypes);
} else {
for (int i = 0; i < headerClusteringTypes.size(); i++) {
AbstractType<?> headerType = headerClusteringTypes.get(i);
ColumnMetadata column = schemaClustering.get(i);
AbstractType<?> schemaType = column.type;
AbstractType<?> fixedType = fixType(desc, column.name.bytes, headerType, schemaType, false);
if (fixedType == null)
clusteringMismatch = true;
else
headerType = fixedType;
clusteringTypes.add(headerType);
}
}
if (clusteringMismatch)
error("sstable %s: mismatch in clustering columns between sstable serialization-header and schema (%s vs %s)", desc, headerClusteringTypes.stream().map(AbstractType::asCQL3Type).map(CQL3Type::toString).collect(Collectors.joining(",")), schemaClustering.stream().map(cd -> cd.type.asCQL3Type().toString()).collect(Collectors.joining(",")));
return clusteringTypes;
}
use of org.apache.cassandra.db.marshal.AbstractType in project cassandra by apache.
the class SliceTest method testIntersectsSingleSlice.
@Test
public void testIntersectsSingleSlice() {
List<AbstractType<?>> types = new ArrayList<>();
types.add(Int32Type.instance);
types.add(Int32Type.instance);
types.add(Int32Type.instance);
ClusteringComparator cc = new ClusteringComparator(types);
ClusteringPrefix.Kind sk = INCL_START_BOUND;
ClusteringPrefix.Kind ek = INCL_END_BOUND;
// filter falls entirely before sstable
Slice slice = Slice.make(makeBound(sk, 0, 0, 0), makeBound(ek, 1, 0, 0));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// same case, but with empty start
slice = Slice.make(makeBound(sk), makeBound(ek, 1, 0, 0));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// same case, but with missing components for start
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 0, 0));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// same case, but with missing components for start and end
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 0));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// end of slice matches start of sstable for the first component, but not the second component
slice = Slice.make(makeBound(sk, 0, 0, 0), makeBound(ek, 1, 0, 0));
assertFalse(slice.intersects(cc, columnNames(1, 1, 0), columnNames(3, 0, 0)));
// same case, but with missing components for start
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 0, 0));
assertFalse(slice.intersects(cc, columnNames(1, 1, 0), columnNames(3, 0, 0)));
// same case, but with missing components for start and end
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 0));
assertFalse(slice.intersects(cc, columnNames(1, 1, 0), columnNames(3, 0, 0)));
// first two components match, but not the last
slice = Slice.make(makeBound(sk, 0, 0, 0), makeBound(ek, 1, 1, 0));
assertFalse(slice.intersects(cc, columnNames(1, 1, 1), columnNames(3, 1, 1)));
// all three components in slice end match the start of the sstable
slice = Slice.make(makeBound(sk, 0, 0, 0), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 1, 1), columnNames(3, 1, 1)));
// filter falls entirely after sstable
slice = Slice.make(makeBound(sk, 4, 0, 0), makeBound(ek, 4, 0, 0));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// same case, but with empty end
slice = Slice.make(makeBound(sk, 4, 0, 0), makeBound(ek));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// same case, but with missing components for end
slice = Slice.make(makeBound(sk, 4, 0, 0), makeBound(ek, 1));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// same case, but with missing components for start and end
slice = Slice.make(makeBound(sk, 4, 0), makeBound(ek, 1));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
// start of slice matches end of sstable for the first component, but not the second component
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek, 2, 0, 0));
assertFalse(slice.intersects(cc, columnNames(0, 0, 0), columnNames(1, 0, 0)));
// start of slice matches end of sstable for the first two components, but not the last component
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek, 2, 0, 0));
assertFalse(slice.intersects(cc, columnNames(0, 0, 0), columnNames(1, 1, 0)));
// all three components in the slice start match the end of the sstable
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek, 2, 0, 0));
assertTrue(slice.intersects(cc, columnNames(0, 0, 0), columnNames(1, 1, 1)));
// slice covers entire sstable (with no matching edges)
slice = Slice.make(makeBound(sk, 0, 0, 0), makeBound(ek, 2, 0, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// same case, but with empty ends
slice = Slice.make(makeBound(sk), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// same case, but with missing components
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 2, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// slice covers entire sstable (with matching start)
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 2, 0, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// slice covers entire sstable (with matching end)
slice = Slice.make(makeBound(sk, 0, 0, 0), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// slice covers entire sstable (with matching start and end)
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// slice falls entirely within sstable (with matching start)
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 1, 1, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// same case, but with a missing end component
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// slice falls entirely within sstable (with matching end)
slice = Slice.make(makeBound(sk, 1, 1, 0), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// same case, but with a missing start component
slice = Slice.make(makeBound(sk, 1, 1), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(1, 1, 1)));
// slice falls entirely within sstable
slice = Slice.make(makeBound(sk, 1, 1, 0), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 2, 2)));
// same case, but with a missing start component
slice = Slice.make(makeBound(sk, 1, 1), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 2, 2)));
// same case, but with a missing start and end components
slice = Slice.make(makeBound(sk, 1), makeBound(ek, 1, 2));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 2, 2)));
// same case, but with an equal first component and missing start and end components
slice = Slice.make(makeBound(sk, 1), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 2, 2)));
// slice falls entirely within sstable (slice start and end are the same)
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 2, 2)));
// slice starts within sstable, empty end
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// same case, but with missing end components
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek, 3));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// slice starts within sstable (matching sstable start), empty end
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// same case, but with missing end components
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 3));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// slice starts within sstable (matching sstable end), empty end
slice = Slice.make(makeBound(sk, 2, 0, 0), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// same case, but with missing end components
slice = Slice.make(makeBound(sk, 2, 0, 0), makeBound(ek, 3));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// slice ends within sstable, empty end
slice = Slice.make(makeBound(sk), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// same case, but with missing start components
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 1, 1));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// slice ends within sstable (matching sstable start), empty start
slice = Slice.make(makeBound(sk), makeBound(ek, 1, 0, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// same case, but with missing start components
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 0, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// slice ends within sstable (matching sstable end), empty start
slice = Slice.make(makeBound(sk), makeBound(ek, 2, 0, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// same case, but with missing start components
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 2, 0, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 0, 0)));
// empty min/max column names
slice = Slice.make(makeBound(sk), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(), columnNames()));
slice = Slice.make(makeBound(sk, 1), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(), columnNames()));
slice = Slice.make(makeBound(sk), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(), columnNames()));
slice = Slice.make(makeBound(sk, 1), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(), columnNames()));
slice = Slice.make(makeBound(sk), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(), columnNames(2)));
slice = Slice.make(makeBound(sk), makeBound(ek, 2));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk, 2), makeBound(ek, 3));
assertFalse(slice.intersects(cc, columnNames(), columnNames(1)));
// basic check on reversed slices
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 0, 0, 0));
assertFalse(slice.intersects(cc, columnNames(2, 0, 0), columnNames(3, 0, 0)));
slice = Slice.make(makeBound(sk, 1, 0, 0), makeBound(ek, 0, 0, 0));
assertFalse(slice.intersects(cc, columnNames(1, 1, 0), columnNames(3, 0, 0)));
slice = Slice.make(makeBound(sk, 1, 1, 1), makeBound(ek, 1, 1, 0));
assertTrue(slice.intersects(cc, columnNames(1, 0, 0), columnNames(2, 2, 2)));
}
use of org.apache.cassandra.db.marshal.AbstractType in project cassandra by apache.
the class SliceTest method testDifferentMinMaxLengths.
@Test
public void testDifferentMinMaxLengths() {
List<AbstractType<?>> types = new ArrayList<>();
types.add(Int32Type.instance);
types.add(Int32Type.instance);
types.add(Int32Type.instance);
ClusteringComparator cc = new ClusteringComparator(types);
ClusteringPrefix.Kind sk = INCL_START_BOUND;
ClusteringPrefix.Kind ek = INCL_END_BOUND;
// slice does intersect
Slice slice = Slice.make(makeBound(sk), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(1), columnNames(1, 2)));
slice = Slice.make(makeBound(sk), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk, 1), makeBound(ek));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk, 1), makeBound(ek, 1));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 1, 2, 3));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk, 1, 2, 3), makeBound(ek, 2));
assertTrue(slice.intersects(cc, columnNames(), columnNames(1)));
// slice does not intersect
slice = Slice.make(makeBound(sk, 2), makeBound(ek, 3, 4, 5));
assertFalse(slice.intersects(cc, columnNames(), columnNames(1)));
slice = Slice.make(makeBound(sk, 0), makeBound(ek, 0, 1, 2));
assertFalse(slice.intersects(cc, columnNames(1), columnNames(1, 2)));
}
use of org.apache.cassandra.db.marshal.AbstractType in project cassandra by apache.
the class CreateFunctionStatement method apply.
// TODO: replace affected aggregates !!
public Keyspaces apply(Keyspaces schema) {
if (ifNotExists && orReplace)
throw ire("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives");
UDFunction.assertUdfsEnabled(language);
if (new HashSet<>(argumentNames).size() != argumentNames.size())
throw ire("Duplicate argument names for given function %s with argument names %s", functionName, argumentNames);
rawArgumentTypes.stream().filter(raw -> !raw.isTuple() && raw.isFrozen()).findFirst().ifPresent(t -> {
throw ire("Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'", t, t);
});
if (!rawReturnType.isTuple() && rawReturnType.isFrozen())
throw ire("Return type '%s' cannot be frozen; remove frozen<> modifier from '%s'", rawReturnType, rawReturnType);
KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
if (null == keyspace)
throw ire("Keyspace '%s' doesn't exist", keyspaceName);
List<AbstractType<?>> argumentTypes = rawArgumentTypes.stream().map(t -> t.prepare(keyspaceName, keyspace.types).getType()).collect(toList());
AbstractType<?> returnType = rawReturnType.prepare(keyspaceName, keyspace.types).getType();
UDFunction function = UDFunction.create(new FunctionName(keyspaceName, functionName), argumentNames, argumentTypes, returnType, calledOnNullInput, language, body);
Function existingFunction = keyspace.functions.find(function.name(), argumentTypes).orElse(null);
if (null != existingFunction) {
if (existingFunction.isAggregate())
throw ire("Function '%s' cannot replace an aggregate", functionName);
if (ifNotExists)
return schema;
if (!orReplace)
throw ire("Function '%s' already exists", functionName);
if (calledOnNullInput != ((UDFunction) existingFunction).isCalledOnNullInput()) {
throw ire("Function '%s' must have %s directive", functionName, calledOnNullInput ? "CALLED ON NULL INPUT" : "RETURNS NULL ON NULL INPUT");
}
if (!returnType.isCompatibleWith(existingFunction.returnType())) {
throw ire("Cannot replace function '%s', the new return type %s is not compatible with the return type %s of existing function", functionName, returnType.asCQL3Type(), existingFunction.returnType().asCQL3Type());
}
// TODO: update dependent aggregates
}
return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.functions.withAddedOrUpdated(function)));
}
Aggregations