Search in sources :

Example 6 with Function

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

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

the class Terms method ofListMarker.

/**
 * Creates a {@code Terms} for the specified list marker.
 *
 * @param marker the list  marker
 * @param type the element type
 * @return a {@code Terms} for the specified list marker
 */
public static Terms ofListMarker(final Lists.Marker marker, final AbstractType<?> type) {
    return new Terms() {

        @Override
        public void addFunctionsTo(List<Function> functions) {
        }

        @Override
        public void collectMarkerSpecification(VariableSpecifications boundNames) {
            marker.collectMarkerSpecification(boundNames);
        }

        @Override
        public List<ByteBuffer> bindAndGet(QueryOptions options) {
            Terminal terminal = marker.bind(options);
            if (terminal == null)
                return null;
            if (terminal == Constants.UNSET_VALUE)
                return UNSET_LIST;
            return ((MultiItemTerminal) terminal).getElements();
        }

        @Override
        public List<Terminal> bind(QueryOptions options) {
            Terminal terminal = marker.bind(options);
            if (terminal == null)
                return null;
            if (terminal == Constants.UNSET_VALUE)
                return UNSET_LIST;
            java.util.function.Function<ByteBuffer, Term.Terminal> deserializer = deserializer(options.getProtocolVersion());
            List<ByteBuffer> boundValues = ((MultiItemTerminal) terminal).getElements();
            List<Term.Terminal> values = new ArrayList<>(boundValues.size());
            for (int i = 0, m = boundValues.size(); i < m; i++) {
                ByteBuffer buffer = boundValues.get(i);
                Term.Terminal value = buffer == null ? null : deserializer.apply(buffer);
                values.add(value);
            }
            return values;
        }

        public java.util.function.Function<ByteBuffer, Term.Terminal> deserializer(ProtocolVersion version) {
            if (type.isCollection()) {
                switch(((CollectionType<?>) type).kind) {
                    case LIST:
                        return e -> Lists.Value.fromSerialized(e, (ListType<?>) type, version);
                    case SET:
                        return e -> Sets.Value.fromSerialized(e, (SetType<?>) type, version);
                    case MAP:
                        return e -> Maps.Value.fromSerialized(e, (MapType<?, ?>) type, version);
                }
                throw new AssertionError();
            }
            return e -> new Constants.Value(e);
        }
    };
}
Also used : MultiItemTerminal(org.apache.cassandra.cql3.Term.MultiItemTerminal) Terminal(org.apache.cassandra.cql3.Term.Terminal) java.util(java.util) Function(org.apache.cassandra.cql3.functions.Function) org.apache.cassandra.db.marshal(org.apache.cassandra.db.marshal) MultiItemTerminal(org.apache.cassandra.cql3.Term.MultiItemTerminal) ProtocolVersion(org.apache.cassandra.transport.ProtocolVersion) ByteBuffer(java.nio.ByteBuffer) ProtocolVersion(org.apache.cassandra.transport.ProtocolVersion) ByteBuffer(java.nio.ByteBuffer) Terminal(org.apache.cassandra.cql3.Term.Terminal) MultiItemTerminal(org.apache.cassandra.cql3.Term.MultiItemTerminal) Terminal(org.apache.cassandra.cql3.Term.Terminal)

Example 8 with Function

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

the class UFIdentificationTest method assertFunctions.

private void assertFunctions(String cql, String... function) {
    CQLStatement stmt = QueryProcessor.getStatement(cql, ClientState.forInternalCalls());
    assertFunctions(stmt, function);
}
Also used : CQLStatement(org.apache.cassandra.cql3.CQLStatement)

Example 9 with Function

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

the class UFJavaTest method testJavaKeyspaceFunction.

@Test
public void testJavaKeyspaceFunction() throws Throwable {
    createTable("CREATE TABLE %s (key int primary key, val double)");
    String functionBody = '\n' + "  // parameter val is of type java.lang.Double\n" + "  /* return type is of type java.lang.Double */\n" + "  if (val == null) {\n" + "    return null;\n" + "  }\n" + "  return Math.sin( val );\n";
    String fName = createFunction(KEYSPACE_PER_TEST, "double", "CREATE OR REPLACE FUNCTION %s(val double) " + "CALLED ON NULL INPUT " + "RETURNS double " + "LANGUAGE JAVA " + "AS '" + functionBody + "';");
    FunctionName fNameName = parseFunctionName(fName);
    assertRows(execute("SELECT language, body FROM system_schema.functions WHERE keyspace_name=? AND function_name=?", fNameName.keyspace, fNameName.name), row("java", functionBody));
    execute("INSERT INTO %s (key, val) VALUES (?, ?)", 1, 1d);
    execute("INSERT INTO %s (key, val) VALUES (?, ?)", 2, 2d);
    execute("INSERT INTO %s (key, val) VALUES (?, ?)", 3, 3d);
    assertRows(execute("SELECT key, val, " + fName + "(val) FROM %s"), row(1, 1d, Math.sin(1d)), row(2, 2d, Math.sin(2d)), row(3, 3d, Math.sin(3d)));
}
Also used : FunctionName(org.apache.cassandra.cql3.functions.FunctionName) Test(org.junit.Test)

Example 10 with Function

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

Aggregations

Test (org.junit.Test)34 Function (io.reactivex.rxjava3.functions.Function)20 FunctionName (org.apache.cassandra.cql3.functions.FunctionName)13 ByteBuffer (java.nio.ByteBuffer)7 Function (org.apache.cassandra.cql3.functions.Function)7 AbstractType (org.apache.cassandra.db.marshal.AbstractType)6 InvalidRequestException (org.apache.cassandra.exceptions.InvalidRequestException)6 KeyspaceMetadata (org.apache.cassandra.schema.KeyspaceMetadata)6 TableMetadata (org.apache.cassandra.schema.TableMetadata)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 ColumnMetadata (org.apache.cassandra.schema.ColumnMetadata)5 ProtocolVersion (org.apache.cassandra.transport.ProtocolVersion)5 InOrder (org.mockito.InOrder)5 List (java.util.List)4 UntypedResultSet (org.apache.cassandra.cql3.UntypedResultSet)4 UDFunction (org.apache.cassandra.cql3.functions.UDFunction)4 ViewMetadata (org.apache.cassandra.schema.ViewMetadata)4 TestException (io.reactivex.rxjava3.exceptions.TestException)3 java.util (java.util)3 ArrayList (java.util.ArrayList)3