Search in sources :

Example 1 with Function

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

the class ModificationStatement method checkAccess.

public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException {
    state.hasColumnFamilyAccess(metadata, Permission.MODIFY);
    // CAS updates can be used to simulate a SELECT query, so should require Permission.SELECT as well.
    if (hasConditions())
        state.hasColumnFamilyAccess(metadata, Permission.SELECT);
    // MV updates need to get the current state from the table, and might update the views
    // Require Permission.SELECT on the base table, and Permission.MODIFY on the views
    Iterator<ViewMetadata> views = View.findAll(keyspace(), columnFamily()).iterator();
    if (views.hasNext()) {
        state.hasColumnFamilyAccess(metadata, Permission.SELECT);
        do {
            state.hasColumnFamilyAccess(views.next().metadata, Permission.MODIFY);
        } while (views.hasNext());
    }
    for (Function function : getFunctions()) state.ensureHasPermission(Permission.EXECUTE, function);
}
Also used : Function(org.apache.cassandra.cql3.functions.Function) ViewMetadata(org.apache.cassandra.schema.ViewMetadata)

Example 2 with Function

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

the class FunctionResolver method get.

/**
     * @param keyspace the current keyspace
     * @param name the name of the function
     * @param providedArgs the arguments provided for the function call
     * @param receiverKs the receiver's keyspace
     * @param receiverCf the receiver's table
     * @param receiverType if the receiver type is known (during inserts, for example), this should be the type of
     *                     the receiver
     * @throws InvalidRequestException
     */
public static Function get(String keyspace, FunctionName name, List<? extends AssignmentTestable> providedArgs, String receiverKs, String receiverCf, AbstractType<?> receiverType) throws InvalidRequestException {
    if (name.equalsNativeFunction(TOKEN_FUNCTION_NAME))
        return new TokenFct(Schema.instance.getTableMetadata(receiverKs, receiverCf));
    // due to needing to know the argument types in advance).
    if (name.equalsNativeFunction(ToJsonFct.NAME))
        throw new InvalidRequestException("toJson() may only be used within the selection clause of SELECT statements");
    // Similarly, we can only use fromJson when we know the receiver type (such as inserts)
    if (name.equalsNativeFunction(FromJsonFct.NAME)) {
        if (receiverType == null)
            throw new InvalidRequestException("fromJson() cannot be used in the selection clause of a SELECT statement");
        return FromJsonFct.getInstance(receiverType);
    }
    Collection<Function> candidates;
    if (!name.hasKeyspace()) {
        // function name not fully qualified
        candidates = new ArrayList<>();
        // add 'SYSTEM' (native) candidates
        candidates.addAll(Schema.instance.getFunctions(name.asNativeFunction()));
        // add 'current keyspace' candidates
        candidates.addAll(Schema.instance.getFunctions(new FunctionName(keyspace, name.name)));
    } else {
        // function name is fully qualified (keyspace + name)
        candidates = Schema.instance.getFunctions(name);
    }
    if (candidates.isEmpty())
        return null;
    // Fast path if there is only one choice
    if (candidates.size() == 1) {
        Function fun = candidates.iterator().next();
        validateTypes(keyspace, fun, providedArgs, receiverKs, receiverCf);
        return fun;
    }
    List<Function> compatibles = null;
    for (Function toTest : candidates) {
        if (matchReturnType(toTest, receiverType)) {
            AssignmentTestable.TestResult r = matchAguments(keyspace, toTest, providedArgs, receiverKs, receiverCf);
            switch(r) {
                case EXACT_MATCH:
                    // We always favor exact matches
                    return toTest;
                case WEAKLY_ASSIGNABLE:
                    if (compatibles == null)
                        compatibles = new ArrayList<>();
                    compatibles.add(toTest);
                    break;
            }
        }
    }
    if (compatibles == null) {
        if (OperationFcts.isOperation(name))
            throw invalidRequest("the '%s' operation is not supported between %s and %s", OperationFcts.getOperator(name), providedArgs.get(0), providedArgs.get(1));
        throw invalidRequest("Invalid call to function %s, none of its type signatures match (known type signatures: %s)", name, format(candidates));
    }
    if (compatibles.size() > 1) {
        if (OperationFcts.isOperation(name)) {
            if (receiverType != null && !containsMarkers(providedArgs)) {
                for (Function toTest : compatibles) {
                    List<AbstractType<?>> argTypes = toTest.argTypes();
                    if (receiverType.equals(argTypes.get(0)) && receiverType.equals(argTypes.get(1)))
                        return toTest;
                }
            }
            throw invalidRequest("Ambiguous '%s' operation: use type casts to disambiguate", OperationFcts.getOperator(name), providedArgs.get(0), providedArgs.get(1));
        }
        if (OperationFcts.isNegation(name))
            throw invalidRequest("Ambiguous negation: use type casts to disambiguate");
        throw invalidRequest("Ambiguous call to function %s (can be matched by following signatures: %s): use type casts to disambiguate", name, format(compatibles));
    }
    return compatibles.get(0);
}
Also used : AssignmentTestable(org.apache.cassandra.cql3.AssignmentTestable) ArrayList(java.util.ArrayList) AbstractType(org.apache.cassandra.db.marshal.AbstractType) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException)

Example 3 with Function

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

the class UDFunction method toCqlString.

@Override
public String toCqlString(boolean withInternals, boolean ifNotExists) {
    CqlBuilder builder = new CqlBuilder();
    builder.append("CREATE FUNCTION ");
    if (ifNotExists) {
        builder.append("IF NOT EXISTS ");
    }
    builder.append(name()).append("(");
    for (int i = 0, m = argNames().size(); i < m; i++) {
        if (i > 0)
            builder.append(", ");
        builder.append(argNames().get(i)).append(' ').append(toCqlString(argTypes().get(i)));
    }
    builder.append(')').newLine().increaseIndent().append(isCalledOnNullInput() ? "CALLED" : "RETURNS NULL").append(" ON NULL INPUT").newLine().append("RETURNS ").append(toCqlString(returnType())).newLine().append("LANGUAGE ").append(language()).newLine().append("AS $$").append(body()).append("$$;");
    return builder.toString();
}
Also used : CqlBuilder(org.apache.cassandra.cql3.CqlBuilder)

Example 4 with Function

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

the class FunctionResolver method validateTypes.

// This method and matchArguments are somewhat duplicate, but this method allows us to provide more precise errors in the common
// case where there is no override for a given function. This is thus probably worth the minor code duplication.
private static void validateTypes(String keyspace, Function fun, List<? extends AssignmentTestable> providedArgs, String receiverKs, String receiverCf) {
    if (providedArgs.size() != fun.argTypes().size())
        throw invalidRequest("Invalid number of arguments in call to function %s: %d required but %d provided", fun.name(), fun.argTypes().size(), providedArgs.size());
    for (int i = 0; i < providedArgs.size(); i++) {
        AssignmentTestable provided = providedArgs.get(i);
        // We'll validate the actually provided value at execution time.
        if (provided == null)
            continue;
        ColumnSpecification expected = makeArgSpec(receiverKs, receiverCf, fun, i);
        if (!provided.testAssignment(keyspace, expected).isAssignable())
            throw invalidRequest("Type error: %s cannot be passed as argument %d of function %s of type %s", provided, i, fun.name(), expected.type.asCQL3Type());
    }
}
Also used : AssignmentTestable(org.apache.cassandra.cql3.AssignmentTestable) ColumnSpecification(org.apache.cassandra.cql3.ColumnSpecification)

Example 5 with Function

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

the class StorageService method restoreReplicaCount.

/**
 * Called when an endpoint is removed from the ring. This function checks
 * whether this node becomes responsible for new ranges as a
 * consequence and streams data if needed.
 *
 * This is rather ineffective, but it does not matter so much
 * since this is called very seldom
 *
 * @param endpoint the node that left
 */
private void restoreReplicaCount(InetAddressAndPort endpoint, final InetAddressAndPort notifyEndpoint) {
    Map<String, Multimap<InetAddressAndPort, FetchReplica>> replicasToFetch = new HashMap<>();
    InetAddressAndPort myAddress = FBUtilities.getBroadcastAddressAndPort();
    for (String keyspaceName : Schema.instance.getNonLocalStrategyKeyspaces()) {
        logger.debug("Restoring replica count for keyspace {}", keyspaceName);
        EndpointsByReplica changedReplicas = getChangedReplicasForLeaving(keyspaceName, endpoint, tokenMetadata, Keyspace.open(keyspaceName).getReplicationStrategy());
        Set<LeavingReplica> myNewReplicas = new HashSet<>();
        for (Map.Entry<Replica, Replica> entry : changedReplicas.flattenEntries()) {
            Replica replica = entry.getValue();
            if (replica.endpoint().equals(myAddress)) {
                // Maybe we don't technically need to fetch transient data from somewhere
                // but it's probably not a lot and it probably makes things a hair more resilient to people
                // not running repair when they should.
                myNewReplicas.add(new LeavingReplica(entry.getKey(), entry.getValue()));
            }
        }
        logger.debug("Changed replicas for leaving {}, myNewReplicas {}", changedReplicas, myNewReplicas);
        replicasToFetch.put(keyspaceName, getNewSourceReplicas(keyspaceName, myNewReplicas));
    }
    StreamPlan stream = new StreamPlan(StreamOperation.RESTORE_REPLICA_COUNT);
    replicasToFetch.forEach((keyspaceName, sources) -> {
        logger.debug("Requesting keyspace {} sources", keyspaceName);
        sources.asMap().forEach((sourceAddress, fetchReplicas) -> {
            logger.debug("Source and our replicas are {}", fetchReplicas);
            // Remember whether this node is providing the full or transient replicas for this range. We are going
            // to pass streaming the local instance of Replica for the range which doesn't tell us anything about the source
            // By encoding it as two separate sets we retain this information about the source.
            RangesAtEndpoint full = fetchReplicas.stream().filter(f -> f.remote.isFull()).map(f -> f.local).collect(RangesAtEndpoint.collector(myAddress));
            RangesAtEndpoint transientReplicas = fetchReplicas.stream().filter(f -> f.remote.isTransient()).map(f -> f.local).collect(RangesAtEndpoint.collector(myAddress));
            if (logger.isDebugEnabled())
                logger.debug("Requesting from {} full replicas {} transient replicas {}", sourceAddress, StringUtils.join(full, ", "), StringUtils.join(transientReplicas, ", "));
            stream.requestRanges(sourceAddress, keyspaceName, full, transientReplicas);
        });
    });
    StreamResultFuture future = stream.execute();
    future.addCallback(new FutureCallback<StreamState>() {

        public void onSuccess(StreamState finalState) {
            sendReplicationNotification(notifyEndpoint);
        }

        public void onFailure(Throwable t) {
            logger.warn("Streaming to restore replica count failed", t);
            // We still want to send the notification
            sendReplicationNotification(notifyEndpoint);
        }
    });
}
Also used : TraceKeyspace(org.apache.cassandra.tracing.TraceKeyspace) StorageMetrics(org.apache.cassandra.metrics.StorageMetrics) File(org.apache.cassandra.io.util.File) CommitLog(org.apache.cassandra.db.commitlog.CommitLog) AuthKeyspace(org.apache.cassandra.auth.AuthKeyspace) org.apache.cassandra.utils(org.apache.cassandra.utils) Global.nanoTime(org.apache.cassandra.utils.Clock.Global.nanoTime) StringUtils(org.apache.commons.lang3.StringUtils) TokenFactory(org.apache.cassandra.dht.Token.TokenFactory) VersionAndType(org.apache.cassandra.io.sstable.format.VersionAndType) InetAddress(java.net.InetAddress) SystemDistributedKeyspace(org.apache.cassandra.schema.SystemDistributedKeyspace) SecondaryIndexManager.isIndexColumnFamily(org.apache.cassandra.index.SecondaryIndexManager.isIndexColumnFamily) SecondaryIndexManager.getIndexName(org.apache.cassandra.index.SecondaryIndexManager.getIndexName) Arrays.asList(java.util.Arrays.asList) HintsService(org.apache.cassandra.hints.HintsService) JMXBroadcastExecutor(org.apache.cassandra.utils.progress.jmx.JMXBroadcastExecutor) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) FullQueryLoggerOptions(org.apache.cassandra.fql.FullQueryLoggerOptions) ViewMetadata(org.apache.cassandra.schema.ViewMetadata) Stream(java.util.stream.Stream) Predicate(com.google.common.base.Predicate) CassandraRelevantProperties(org.apache.cassandra.config.CassandraRelevantProperties) FullQueryLogger(org.apache.cassandra.fql.FullQueryLogger) Conflict(org.apache.cassandra.locator.ReplicaCollection.Builder.Conflict) KeyspaceMetadata(org.apache.cassandra.schema.KeyspaceMetadata) LoggingSupportFactory(org.apache.cassandra.utils.logging.LoggingSupportFactory) NoPayload.noPayload(org.apache.cassandra.net.NoPayload.noPayload) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ProgressEvent(org.apache.cassandra.utils.progress.ProgressEvent) java.util(java.util) OpenDataException(javax.management.openmbean.OpenDataException) CompactionManager(org.apache.cassandra.db.compaction.CompactionManager) SSTableLoader(org.apache.cassandra.io.sstable.SSTableLoader) ClientResourceLimits(org.apache.cassandra.transport.ClientResourceLimits) Global.currentTimeMillis(org.apache.cassandra.utils.Clock.Global.currentTimeMillis) Range(org.apache.cassandra.dht.Range) MINUTES(java.util.concurrent.TimeUnit.MINUTES) QueryProcessor(org.apache.cassandra.cql3.QueryProcessor) Supplier(java.util.function.Supplier) REPLICATION_DONE_REQ(org.apache.cassandra.net.Verb.REPLICATION_DONE_REQ) Schema(org.apache.cassandra.schema.Schema) ActiveRepairService(org.apache.cassandra.service.ActiveRepairService) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) FullQueryLoggerOptionsCompositeData(org.apache.cassandra.fql.FullQueryLoggerOptionsCompositeData) Predicates(com.google.common.base.Predicates) BatchlogManager(org.apache.cassandra.batchlog.BatchlogManager) StreamSupport(java.util.stream.StreamSupport) ProgressEventType(org.apache.cassandra.utils.progress.ProgressEventType) Nullable(javax.annotation.Nullable) CompositeData(javax.management.openmbean.CompositeData) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) IOError(java.io.IOError) ExecutionException(java.util.concurrent.ExecutionException) Paths(java.nio.file.Paths) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) org.apache.cassandra.net(org.apache.cassandra.net) SnapshotManager(org.apache.cassandra.service.snapshot.SnapshotManager) Preconditions(com.google.common.base.Preconditions) org.apache.cassandra.locator(org.apache.cassandra.locator) AuditLogManager(org.apache.cassandra.audit.AuditLogManager) Verifier(org.apache.cassandra.db.compaction.Verifier) org.apache.cassandra.repair(org.apache.cassandra.repair) org.apache.cassandra.streaming(org.apache.cassandra.streaming) Iterables.transform(com.google.common.collect.Iterables.transform) Iterables.tryFind(com.google.common.collect.Iterables.tryFind) MatchResult(java.util.regex.MatchResult) LoggerFactory(org.slf4j.LoggerFactory) org.apache.cassandra.db(org.apache.cassandra.db) ReplicationParams(org.apache.cassandra.schema.ReplicationParams) TimeoutException(java.util.concurrent.TimeoutException) org.apache.cassandra.gms(org.apache.cassandra.gms) com.google.common.util.concurrent(com.google.common.util.concurrent) TabularData(javax.management.openmbean.TabularData) ByteBuffer(java.nio.ByteBuffer) MigrationManager(org.apache.cassandra.schema.MigrationManager) ByteArrayInputStream(java.io.ByteArrayInputStream) Collectors.toMap(java.util.stream.Collectors.toMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SSTableFormat(org.apache.cassandra.io.sstable.format.SSTableFormat) AuthSchemaChangeListener(org.apache.cassandra.auth.AuthSchemaChangeListener) PathUtils(org.apache.cassandra.io.util.PathUtils) com.google.common.collect(com.google.common.collect) DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) AuditLogOptions(org.apache.cassandra.audit.AuditLogOptions) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TombstoneOption(org.apache.cassandra.schema.CompactionParams.TombstoneOption) JMXProgressSupport(org.apache.cassandra.utils.progress.jmx.JMXProgressSupport) Instant(java.time.Instant) org.apache.cassandra.dht(org.apache.cassandra.dht) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) UncheckedInterruptedException(org.apache.cassandra.utils.concurrent.UncheckedInterruptedException) ProgressListener(org.apache.cassandra.utils.progress.ProgressListener) AuthCacheService(org.apache.cassandra.auth.AuthCacheService) DurationSpec(org.apache.cassandra.config.DurationSpec) MigrationManager.evolveSystemKeyspace(org.apache.cassandra.schema.MigrationManager.evolveSystemKeyspace) ParameterizedClass(org.apache.cassandra.config.ParameterizedClass) LifecycleTransaction(org.apache.cassandra.db.lifecycle.LifecycleTransaction) Future(org.apache.cassandra.utils.concurrent.Future) org.apache.cassandra.exceptions(org.apache.cassandra.exceptions) FileUtils(org.apache.cassandra.io.util.FileUtils) TableMetadataRef(org.apache.cassandra.schema.TableMetadataRef) TabularDataSupport(javax.management.openmbean.TabularDataSupport) Entry(java.util.Map.Entry) org.apache.cassandra.concurrent(org.apache.cassandra.concurrent) TableMetadata(org.apache.cassandra.schema.TableMetadata) VirtualKeyspaceRegistry(org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry) Pattern(java.util.regex.Pattern) MigrationCoordinator(org.apache.cassandra.schema.MigrationCoordinator) SchemaConstants(org.apache.cassandra.schema.SchemaConstants) Arrays.stream(java.util.Arrays.stream) DataInputStream(java.io.DataInputStream) RepairOption(org.apache.cassandra.repair.messages.RepairOption) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) Config(org.apache.cassandra.config.Config) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) QueryHandler(org.apache.cassandra.cql3.QueryHandler) BOOTSTRAP_SKIP_SCHEMA_CHECK(org.apache.cassandra.config.CassandraRelevantProperties.BOOTSTRAP_SKIP_SCHEMA_CHECK) FetchReplica(org.apache.cassandra.dht.RangeStreamer.FetchReplica) ProtocolVersion(org.apache.cassandra.transport.ProtocolVersion) ExecutorService(java.util.concurrent.ExecutorService) Logger(org.slf4j.Logger) javax.management(javax.management) REPLACEMENT_ALLOW_EMPTY(org.apache.cassandra.config.CassandraRelevantProperties.REPLACEMENT_ALLOW_EMPTY) TimeUnit(java.util.concurrent.TimeUnit) Collectors.toList(java.util.stream.Collectors.toList) VisibleForTesting(com.google.common.annotations.VisibleForTesting) BOOTSTRAP_SCHEMA_DELAY_MS(org.apache.cassandra.config.CassandraRelevantProperties.BOOTSTRAP_SCHEMA_DELAY_MS) TableSnapshot(org.apache.cassandra.service.snapshot.TableSnapshot) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) FetchReplica(org.apache.cassandra.dht.RangeStreamer.FetchReplica) Collectors.toMap(java.util.stream.Collectors.toMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

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