Search in sources :

Example 1 with UDFunction

use of org.apache.cassandra.cql3.functions.UDFunction 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)

Example 2 with UDFunction

use of org.apache.cassandra.cql3.functions.UDFunction in project cassandra by apache.

the class SchemaKeyspace method createUDAFromRow.

private static UDAggregate createUDAFromRow(UntypedResultSet.Row row, Collection<UDFunction> functions, Types types) {
    String ksName = row.getString("keyspace_name");
    String functionName = row.getString("aggregate_name");
    FunctionName name = new FunctionName(ksName, functionName);
    List<AbstractType<?>> argTypes = row.getFrozenList("argument_types", UTF8Type.instance).stream().map(t -> CQLTypeParser.parse(ksName, t, types)).collect(toList());
    AbstractType<?> returnType = CQLTypeParser.parse(ksName, row.getString("return_type"), types);
    FunctionName stateFunc = new FunctionName(ksName, (row.getString("state_func")));
    FunctionName finalFunc = row.has("final_func") ? new FunctionName(ksName, row.getString("final_func")) : null;
    AbstractType<?> stateType = row.has("state_type") ? CQLTypeParser.parse(ksName, row.getString("state_type"), types) : null;
    ByteBuffer initcond = row.has("initcond") ? Terms.asBytes(ksName, row.getString("initcond"), stateType) : null;
    return UDAggregate.create(functions, name, argTypes, returnType, stateFunc, finalFunc, stateType, initcond);
}
Also used : org.apache.cassandra.config(org.apache.cassandra.config) java.util(java.util) CharacterCodingException(java.nio.charset.CharacterCodingException) org.apache.cassandra.db.marshal(org.apache.cassandra.db.marshal) LoggerFactory(org.slf4j.LoggerFactory) org.apache.cassandra.db(org.apache.cassandra.db) ByteBuffer(java.nio.ByteBuffer) org.apache.cassandra.cql3(org.apache.cassandra.cql3) org.apache.cassandra.db.rows(org.apache.cassandra.db.rows) SchemaKeyspaceTables(org.apache.cassandra.schema.SchemaKeyspaceTables) RecognitionException(org.antlr.runtime.RecognitionException) Simulate(org.apache.cassandra.utils.Simulate) ColumnFilter(org.apache.cassandra.db.filter.ColumnFilter) ProtocolVersion(org.apache.cassandra.transport.ProtocolVersion) org.apache.cassandra.cql3.functions(org.apache.cassandra.cql3.functions) KeyspacesDiff(org.apache.cassandra.schema.Keyspaces.KeyspacesDiff) com.google.common.collect(com.google.common.collect) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException) SpeculativeRetryPolicy(org.apache.cassandra.service.reads.SpeculativeRetryPolicy) org.apache.cassandra.db.partitions(org.apache.cassandra.db.partitions) Collectors.toSet(java.util.stream.Collectors.toSet) ClusteringOrder(org.apache.cassandra.schema.ColumnMetadata.ClusteringOrder) Logger(org.slf4j.Logger) FBUtilities(org.apache.cassandra.utils.FBUtilities) ByteBufferUtil(org.apache.cassandra.utils.ByteBufferUtil) QueryProcessor.executeInternal(org.apache.cassandra.cql3.QueryProcessor.executeInternal) Collectors(java.util.stream.Collectors) Maps(com.google.common.collect.Maps) ReadRepairStrategy(org.apache.cassandra.service.reads.repair.ReadRepairStrategy) String.format(java.lang.String.format) QueryProcessor.executeOnceInternal(org.apache.cassandra.cql3.QueryProcessor.executeOnceInternal) CreateTableStatement(org.apache.cassandra.cql3.statements.schema.CreateTableStatement) TimeUnit(java.util.concurrent.TimeUnit) GLOBAL_CLOCK(org.apache.cassandra.utils.Simulate.With.GLOBAL_CLOCK) Collectors.toList(java.util.stream.Collectors.toList) VisibleForTesting(com.google.common.annotations.VisibleForTesting) NotThreadSafe(javax.annotation.concurrent.NotThreadSafe) ByteBuffer(java.nio.ByteBuffer)

Example 3 with UDFunction

use of org.apache.cassandra.cql3.functions.UDFunction in project cassandra by apache.

the class UFJavaTest method testUDAToCqlString.

@Test
public void testUDAToCqlString() throws Throwable {
    // we have to create this function in DB otherwise UDAggregate creation below fails
    String stateFunctionName = createFunction(KEYSPACE, "int,int", "CREATE OR REPLACE FUNCTION %s(state int, val int)\n" + "    CALLED ON NULL INPUT\n" + "    RETURNS int\n" + "    LANGUAGE java\n" + "    AS $$\n" + "        return state + val;\n" + "    $$;");
    // Java representation of state function so we can construct aggregate programmatically
    UDFunction stateFunction = UDFunction.create(new FunctionName(KEYSPACE, stateFunctionName.split("\\.")[1]), Arrays.asList(ColumnIdentifier.getInterned("state", false), ColumnIdentifier.getInterned("val", false)), Arrays.asList(Int32Type.instance, Int32Type.instance), Int32Type.instance, true, "java", "return state + val;");
    UDAggregate aggregate = UDAggregate.create(Collections.singleton(stateFunction), new FunctionName(KEYSPACE, "my_aggregate"), Collections.singletonList(Int32Type.instance), Int32Type.instance, new FunctionName(KEYSPACE, stateFunctionName.split("\\.")[1]), null, Int32Type.instance, null);
    Assert.assertTrue(aggregate.toCqlString(true, true).contains("CREATE AGGREGATE IF NOT EXISTS"));
    Assert.assertFalse(aggregate.toCqlString(true, false).contains("CREATE AGGREGATE IF NOT EXISTS"));
    Assert.assertEquals(aggregate.toCqlString(true, true), aggregate.toCqlString(false, true));
    Assert.assertEquals(aggregate.toCqlString(true, false), aggregate.toCqlString(false, false));
}
Also used : FunctionName(org.apache.cassandra.cql3.functions.FunctionName) UDAggregate(org.apache.cassandra.cql3.functions.UDAggregate) UDFunction(org.apache.cassandra.cql3.functions.UDFunction) Test(org.junit.Test)

Example 4 with UDFunction

use of org.apache.cassandra.cql3.functions.UDFunction in project cassandra by apache.

the class UFJavaTest method testUDFToCqlString.

@Test
public void testUDFToCqlString() {
    UDFunction function = UDFunction.create(new FunctionName("my_ks", "my_function"), Arrays.asList(ColumnIdentifier.getInterned("column", false)), Arrays.asList(UTF8Type.instance), Int32Type.instance, false, "java", "return 0;");
    Assert.assertTrue(function.toCqlString(true, true).contains("CREATE FUNCTION IF NOT EXISTS"));
    Assert.assertFalse(function.toCqlString(true, false).contains("CREATE FUNCTION IF NOT EXISTS"));
    Assert.assertEquals(function.toCqlString(true, true), function.toCqlString(false, true));
    Assert.assertEquals(function.toCqlString(true, false), function.toCqlString(false, false));
}
Also used : FunctionName(org.apache.cassandra.cql3.functions.FunctionName) UDFunction(org.apache.cassandra.cql3.functions.UDFunction) Test(org.junit.Test)

Example 5 with UDFunction

use of org.apache.cassandra.cql3.functions.UDFunction in project cassandra by apache.

the class UFTest method testBrokenFunction.

@Test
public void testBrokenFunction() throws Throwable {
    createTable("CREATE TABLE %s (key int primary key, dval double)");
    execute("INSERT INTO %s (key, dval) VALUES (?, ?)", 1, 1d);
    String fName = createFunction(KEYSPACE_PER_TEST, "double", "CREATE OR REPLACE FUNCTION %s(val double) " + "RETURNS NULL ON NULL INPUT " + "RETURNS double " + "LANGUAGE JAVA\n" + "AS 'throw new RuntimeException();';");
    KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(KEYSPACE_PER_TEST);
    UDFunction f = (UDFunction) ksm.functions.get(parseFunctionName(fName)).iterator().next();
    UDFunction broken = UDFunction.createBrokenFunction(f.name(), f.argNames(), f.argTypes(), f.returnType(), true, "java", f.body(), new InvalidRequestException("foo bar is broken"));
    Schema.instance.load(ksm.withSwapped(ksm.functions.without(f.name(), f.argTypes()).with(broken)));
    assertInvalidThrowMessage("foo bar is broken", InvalidRequestException.class, "SELECT key, " + fName + "(dval) FROM %s");
}
Also used : InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException) KeyspaceMetadata(org.apache.cassandra.schema.KeyspaceMetadata) JavaBasedUDFunction(org.apache.cassandra.cql3.functions.JavaBasedUDFunction) UDFunction(org.apache.cassandra.cql3.functions.UDFunction) Test(org.junit.Test)

Aggregations

UDFunction (org.apache.cassandra.cql3.functions.UDFunction)4 Collectors.toList (java.util.stream.Collectors.toList)3 FunctionName (org.apache.cassandra.cql3.functions.FunctionName)3 KeyspaceMetadata (org.apache.cassandra.schema.KeyspaceMetadata)3 KeyspacesDiff (org.apache.cassandra.schema.Keyspaces.KeyspacesDiff)3 Test (org.junit.Test)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Lists (com.google.common.collect.Lists)2 String.format (java.lang.String.format)2 ByteBuffer (java.nio.ByteBuffer)2 List (java.util.List)2 Set (java.util.Set)2 AuditLogContext (org.apache.cassandra.audit.AuditLogContext)2 AuditLogEntryType (org.apache.cassandra.audit.AuditLogEntryType)2 org.apache.cassandra.cql3 (org.apache.cassandra.cql3)2 org.apache.cassandra.cql3.functions (org.apache.cassandra.cql3.functions)2 InvalidRequestException (org.apache.cassandra.exceptions.InvalidRequestException)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Objects (com.google.common.base.Objects)1 com.google.common.collect (com.google.common.collect)1