Search in sources :

Example 6 with AbstractType

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));
}
Also used : TableMetadata(org.apache.cassandra.schema.TableMetadata) MetadataComponent(org.apache.cassandra.io.sstable.metadata.MetadataComponent) MetadataType(org.apache.cassandra.io.sstable.metadata.MetadataType) ByteBuffer(java.nio.ByteBuffer) LinkedHashMap(java.util.LinkedHashMap) SerializationHeader(org.apache.cassandra.db.SerializationHeader) AbstractType(org.apache.cassandra.db.marshal.AbstractType) MetadataComponent(org.apache.cassandra.io.sstable.metadata.MetadataComponent)

Example 7 with AbstractType

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;
}
Also used : CharacterCodingException(java.nio.charset.CharacterCodingException) ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata) IndexTarget(org.apache.cassandra.cql3.statements.schema.IndexTarget) File(org.apache.cassandra.io.util.File) LoggerFactory(org.slf4j.LoggerFactory) SetType(org.apache.cassandra.db.marshal.SetType) AbstractType(org.apache.cassandra.db.marshal.AbstractType) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) Schema(org.apache.cassandra.schema.Schema) LinkedHashMap(java.util.LinkedHashMap) ListType(org.apache.cassandra.db.marshal.ListType) CQL3Type(org.apache.cassandra.cql3.CQL3Type) AbstractCompositeType(org.apache.cassandra.db.marshal.AbstractCompositeType) Pair(org.apache.cassandra.utils.Pair) TupleType(org.apache.cassandra.db.marshal.TupleType) Map(java.util.Map) MetadataComponent(org.apache.cassandra.io.sstable.metadata.MetadataComponent) CassandraVersion(org.apache.cassandra.utils.CassandraVersion) Path(java.nio.file.Path) SerializationHeader(org.apache.cassandra.db.SerializationHeader) EnumSet(java.util.EnumSet) CollectionType(org.apache.cassandra.db.marshal.CollectionType) CompositeType(org.apache.cassandra.db.marshal.CompositeType) Logger(org.slf4j.Logger) FBUtilities(org.apache.cassandra.utils.FBUtilities) IndexMetadata(org.apache.cassandra.schema.IndexMetadata) Files(java.nio.file.Files) MetadataType(org.apache.cassandra.io.sstable.metadata.MetadataType) ByteBufferUtil(org.apache.cassandra.utils.ByteBufferUtil) Set(java.util.Set) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Consumer(java.util.function.Consumer) List(java.util.List) MapType(org.apache.cassandra.db.marshal.MapType) Stream(java.util.stream.Stream) LifecycleTransaction(org.apache.cassandra.db.lifecycle.LifecycleTransaction) TableMetadata(org.apache.cassandra.schema.TableMetadata) DynamicCompositeType(org.apache.cassandra.db.marshal.DynamicCompositeType) Directories(org.apache.cassandra.db.Directories) SchemaConstants(org.apache.cassandra.schema.SchemaConstants) UserType(org.apache.cassandra.db.marshal.UserType) ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata) AbstractType(org.apache.cassandra.db.marshal.AbstractType) ArrayList(java.util.ArrayList)

Example 8 with AbstractType

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)));
}
Also used : AbstractType(org.apache.cassandra.db.marshal.AbstractType) Kind(org.apache.cassandra.db.ClusteringPrefix.Kind) Test(org.junit.Test)

Example 9 with AbstractType

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)));
}
Also used : AbstractType(org.apache.cassandra.db.marshal.AbstractType) Kind(org.apache.cassandra.db.ClusteringPrefix.Kind) Test(org.junit.Test)

Example 10 with AbstractType

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)));
}
Also used : AuditLogContext(org.apache.cassandra.audit.AuditLogContext) Change(org.apache.cassandra.transport.Event.SchemaChange.Change) CQLStatement(org.apache.cassandra.cql3.CQLStatement) AbstractType(org.apache.cassandra.db.marshal.AbstractType) Schema(org.apache.cassandra.schema.Schema) HashSet(java.util.HashSet) Function(org.apache.cassandra.cql3.functions.Function) Lists(com.google.common.collect.Lists) CQL3Type(org.apache.cassandra.cql3.CQL3Type) FunctionName(org.apache.cassandra.cql3.functions.FunctionName) org.apache.cassandra.auth(org.apache.cassandra.auth) FunctionsDiff(org.apache.cassandra.schema.Functions.FunctionsDiff) UDFunction(org.apache.cassandra.cql3.functions.UDFunction) KeyspacesDiff(org.apache.cassandra.schema.Keyspaces.KeyspacesDiff) ImmutableSet(com.google.common.collect.ImmutableSet) Keyspaces(org.apache.cassandra.schema.Keyspaces) SchemaChange(org.apache.cassandra.transport.Event.SchemaChange) ClientState(org.apache.cassandra.service.ClientState) Set(java.util.Set) AuditLogEntryType(org.apache.cassandra.audit.AuditLogEntryType) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) ColumnIdentifier(org.apache.cassandra.cql3.ColumnIdentifier) Target(org.apache.cassandra.transport.Event.SchemaChange.Target) KeyspaceMetadata(org.apache.cassandra.schema.KeyspaceMetadata) FunctionName(org.apache.cassandra.cql3.functions.FunctionName) Function(org.apache.cassandra.cql3.functions.Function) UDFunction(org.apache.cassandra.cql3.functions.UDFunction) AbstractType(org.apache.cassandra.db.marshal.AbstractType) KeyspaceMetadata(org.apache.cassandra.schema.KeyspaceMetadata) UDFunction(org.apache.cassandra.cql3.functions.UDFunction) HashSet(java.util.HashSet)

Aggregations

AbstractType (org.apache.cassandra.db.marshal.AbstractType)51 ByteBuffer (java.nio.ByteBuffer)20 ColumnMetadata (org.apache.cassandra.schema.ColumnMetadata)9 TableMetadata (org.apache.cassandra.schema.TableMetadata)8 List (java.util.List)6 Map (java.util.Map)6 CollectionType (org.apache.cassandra.db.marshal.CollectionType)6 CompositeType (org.apache.cassandra.db.marshal.CompositeType)6 IOException (java.io.IOException)5 ArrayList (java.util.ArrayList)5 Set (java.util.Set)5 Collectors (java.util.stream.Collectors)5 CQL3Type (org.apache.cassandra.cql3.CQL3Type)5 SerializationHeader (org.apache.cassandra.db.SerializationHeader)5 TupleType (org.apache.cassandra.db.marshal.TupleType)5 UserType (org.apache.cassandra.db.marshal.UserType)5 ColumnIdentifier (org.apache.cassandra.cql3.ColumnIdentifier)4 FieldIdentifier (org.apache.cassandra.cql3.FieldIdentifier)4 Test (org.junit.Test)4 AuditLogContext (org.apache.cassandra.audit.AuditLogContext)3