InvalidRequestException reason) return new UDFunction(name, argNames, argTypes, returnType, calledOnNullInput, language, body)
/** * Used by UDF implementations (both Java code generated by {@link JavaBasedUDFunction} * and script executor {@link ScriptBasedUDFunction}) to convert the C* * serialized representation to the Java object representation. * * @param protocolVersion the native protocol version used for serialization * @param argIndex index of the UDF input argument */ protected Object compose(ProtocolVersion protocolVersion, int argIndex, ByteBuffer value) { return compose(argCodecs, protocolVersion, argIndex, value); }
if (udf.argNames().equals(argNames) && // arg types checked in Functions.find call udf.returnType().equals(returnType) && !udf.isAggregate() && udf.language().equals(language) && udf.body().equals(body) && udf.isCalledOnNullInput() == calledOnNullInput) return UDFunction.create(name, argNames, argTypes, returnType, calledOnNullInput, language, body); return UDFunction.createBrokenFunction(name, argNames, argTypes, returnType, calledOnNullInput, language, body, e);
static void addFunctionToSchemaMutation(UDFunction function, Mutation.SimpleBuilder builder) { builder.update(Functions) .row(function.name().name, functionArgumentsList(function)) .add("body", function.body()) .add("language", function.language()) .add("return_type", function.returnType().asCQL3Type().toString()) .add("called_on_null_input", function.isCalledOnNullInput()) .add("argument_names", function.argNames().stream().map((c) -> bbToString(c.bytes)).collect(toList())); }
public final ByteBuffer execute(ProtocolVersion protocolVersion, List<ByteBuffer> parameters) { assertUdfsEnabled(language); if (!isCallableWrtNullable(parameters)) return null; long tStart = System.nanoTime(); parameters = makeEmptyParametersNull(parameters); try { // Using async UDF execution is expensive (adds about 100us overhead per invocation on a Core-i7 MBPr). ByteBuffer result = DatabaseDescriptor.enableUserDefinedFunctionsThreads() ? executeAsync(protocolVersion, parameters) : executeUserDefined(protocolVersion, parameters); Tracing.trace("Executed UDF {} in {}\u03bcs", name(), (System.nanoTime() - tStart) / 1000); return result; } catch (InvalidRequestException e) { throw e; } catch (Throwable t) { logger.trace("Invocation of user-defined function '{}' failed", this, t); if (t instanceof VirtualMachineError) throw (VirtualMachineError) t; throw FunctionExecutionException.create(this, t); } }
assertUdfsEnabled(language); if (!calledOnNullInput && firstParam == null || !isCallableWrtNullable(parameters)) return null; parameters = makeEmptyParametersNull(parameters); ? executeAggregateAsync(protocolVersion, firstParam, parameters) : executeAggregateUserDefined(protocolVersion, firstParam, parameters); Tracing.trace("Executed UDF {} in {}\u03bcs", name(), (System.nanoTime() - tStart) / 1000); return result;
public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException { Function old = Schema.instance.findFunction(functionName, argTypes).orElse(null); boolean replaced = old != null; if (replaced) { if (ifNotExists) return null; if (!orReplace) throw new InvalidRequestException(String.format("Function %s already exists", old)); if (!(old instanceof ScalarFunction)) throw new InvalidRequestException(String.format("Function %s can only replace a function", old)); if (calledOnNullInput != ((ScalarFunction) old).isCalledOnNullInput()) throw new InvalidRequestException(String.format("Function %s can only be replaced with %s", old, calledOnNullInput ? "CALLED ON NULL INPUT" : "RETURNS NULL ON NULL INPUT")); if (!Functions.typesMatch(old.returnType(), returnType)) throw new InvalidRequestException(String.format("Cannot replace function %s, the new return type %s is not compatible with the return type %s of existing function", functionName, returnType.asCQL3Type(), old.returnType().asCQL3Type())); } UDFunction udFunction = UDFunction.create(functionName, argNames, argTypes, returnType, calledOnNullInput, language, body); MigrationManager.announceNewFunction(udFunction, isLocalOnly); return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.FUNCTION, udFunction.name().keyspace, udFunction.name().name, AbstractType.asCQLTypeStringList(udFunction.argTypes())); }
private ByteBuffer executeAsync(ProtocolVersion protocolVersion, List<ByteBuffer> parameters) { ThreadIdAndCpuTime threadIdAndCpuTime = new ThreadIdAndCpuTime(); return async(threadIdAndCpuTime, () -> { threadIdAndCpuTime.setup(); return executeUserDefined(protocolVersion, parameters); }); }
/** * Like {@link #executeAsync(int, List)} but the first parameter is already in non-serialized form. * Remaining parameters (2nd paramters and all others) are in {@code parameters}. * This is used to prevent superfluous (de)serialization of the state of aggregates. * Means: scalar functions of aggregates are called using this variant. */ private Object executeAggregateAsync(ProtocolVersion protocolVersion, Object firstParam, List<ByteBuffer> parameters) { ThreadIdAndCpuTime threadIdAndCpuTime = new ThreadIdAndCpuTime(); return async(threadIdAndCpuTime, () -> { threadIdAndCpuTime.setup(); return executeAggregateUserDefined(protocolVersion, firstParam, parameters); }); }
public ByteBuffer compute(ProtocolVersion protocolVersion) throws InvalidRequestException { maybeInit(protocolVersion); // final function is traced in UDFunction Tracing.trace("Executed UDA {}: {} call(s) to state function {} in {}\u03bcs", name(), stateFunctionCount, stateFunction.name(), stateFunctionDuration); if (finalFunction == null) return UDFunction.decompose(stateTypeCodec, protocolVersion, state); if (finalFunction instanceof UDFunction) { UDFunction udf = (UDFunction)finalFunction; Object result = udf.executeForAggregate(protocolVersion, state, Collections.emptyList()); return UDFunction.decompose(returnTypeCodec, protocolVersion, result); } throw new UnsupportedOperationException("UDAs only support UDFs"); }
private static UDFunction readFunctionMetadata(String keyspaceName, String functionName, List<String> signature) { String query = format("SELECT * FROM %s.%s WHERE keyspace_name = ? AND function_name = ? AND signature = ?", SchemaConstants.SYSTEM_KEYSPACE_NAME, SystemKeyspace.LEGACY_FUNCTIONS); UntypedResultSet.Row row = query(query, keyspaceName, functionName, signature).one(); FunctionName name = new FunctionName(keyspaceName, functionName); List<ColumnIdentifier> argNames = new ArrayList<>(); if (row.has("argument_names")) for (String arg : row.getList("argument_names", UTF8Type.instance)) argNames.add(new ColumnIdentifier(arg, true)); List<AbstractType<?>> argTypes = new ArrayList<>(); if (row.has("argument_types")) for (String type : row.getList("argument_types", UTF8Type.instance)) argTypes.add(parseType(type)); AbstractType<?> returnType = parseType(row.getString("return_type")); String language = row.getString("language"); String body = row.getString("body"); boolean calledOnNullInput = row.getBoolean("called_on_null_input"); try { return UDFunction.create(name, argNames, argTypes, returnType, calledOnNullInput, language, body); } catch (InvalidRequestException e) { return UDFunction.createBrokenFunction(name, argNames, argTypes, returnType, calledOnNullInput, language, body, e); } }
/** * Used by UDF implementations (both Java code generated by {@link JavaBasedUDFunction} * and script executor {@link ScriptBasedUDFunction}) to convert the Java * object representation for the return value to the C* serialized representation. * * @param protocolVersion the native protocol version used for serialization */ protected ByteBuffer decompose(ProtocolVersion protocolVersion, Object value) { return decompose(returnCodec, protocolVersion, value); }
public void validate(ClientState state) throws InvalidRequestException { UDFunction.assertUdfsEnabled(language); if (ifNotExists && orReplace) throw new InvalidRequestException("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives"); if (Schema.instance.getKSMetaData(functionName.keyspace) == null) throw new InvalidRequestException(String.format("Cannot add function '%s' to non existing keyspace '%s'.", functionName.name, functionName.keyspace)); }
if (udf.argNames().equals(argNames) && // arg types checked in Functions.find call udf.returnType().equals(returnType) && !udf.isAggregate() && udf.language().equals(language) && udf.body().equals(body) && udf.isCalledOnNullInput() == calledOnNullInput) return UDFunction.create(name, argNames, argTypes, returnType, calledOnNullInput, language, body); return UDFunction.createBrokenFunction(name, argNames, argTypes, returnType, calledOnNullInput, language, body, e);
static void addFunctionToSchemaMutation(UDFunction function, Mutation.SimpleBuilder builder) { builder.update(Functions) .row(function.name().name, functionArgumentsList(function)) .add("body", function.body()) .add("language", function.language()) .add("return_type", function.returnType().asCQL3Type().toString()) .add("called_on_null_input", function.isCalledOnNullInput()) .add("argument_names", function.argNames().stream().map((c) -> bbToString(c.bytes)).collect(toList())); }
public final ByteBuffer execute(ProtocolVersion protocolVersion, List<ByteBuffer> parameters) { assertUdfsEnabled(language); if (!isCallableWrtNullable(parameters)) return null; long tStart = System.nanoTime(); parameters = makeEmptyParametersNull(parameters); try { // Using async UDF execution is expensive (adds about 100us overhead per invocation on a Core-i7 MBPr). ByteBuffer result = DatabaseDescriptor.enableUserDefinedFunctionsThreads() ? executeAsync(protocolVersion, parameters) : executeUserDefined(protocolVersion, parameters); Tracing.trace("Executed UDF {} in {}\u03bcs", name(), (System.nanoTime() - tStart) / 1000); return result; } catch (InvalidRequestException e) { throw e; } catch (Throwable t) { logger.trace("Invocation of user-defined function '{}' failed", this, t); if (t instanceof VirtualMachineError) throw (VirtualMachineError) t; throw FunctionExecutionException.create(this, t); } }
assertUdfsEnabled(language); if (!calledOnNullInput && firstParam == null || !isCallableWrtNullable(parameters)) return null; parameters = makeEmptyParametersNull(parameters); ? executeAggregateAsync(protocolVersion, firstParam, parameters) : executeAggregateUserDefined(protocolVersion, firstParam, parameters); Tracing.trace("Executed UDF {} in {}\u03bcs", name(), (System.nanoTime() - tStart) / 1000); return result;
public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException { Function old = Schema.instance.findFunction(functionName, argTypes).orElse(null); boolean replaced = old != null; if (replaced) { if (ifNotExists) return null; if (!orReplace) throw new InvalidRequestException(String.format("Function %s already exists", old)); if (!(old instanceof ScalarFunction)) throw new InvalidRequestException(String.format("Function %s can only replace a function", old)); if (calledOnNullInput != ((ScalarFunction) old).isCalledOnNullInput()) throw new InvalidRequestException(String.format("Function %s can only be replaced with %s", old, calledOnNullInput ? "CALLED ON NULL INPUT" : "RETURNS NULL ON NULL INPUT")); if (!Functions.typesMatch(old.returnType(), returnType)) throw new InvalidRequestException(String.format("Cannot replace function %s, the new return type %s is not compatible with the return type %s of existing function", functionName, returnType.asCQL3Type(), old.returnType().asCQL3Type())); } UDFunction udFunction = UDFunction.create(functionName, argNames, argTypes, returnType, calledOnNullInput, language, body); MigrationManager.announceNewFunction(udFunction, isLocalOnly); return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.FUNCTION, udFunction.name().keyspace, udFunction.name().name, AbstractType.asCQLTypeStringList(udFunction.argTypes())); }
private ByteBuffer executeAsync(ProtocolVersion protocolVersion, List<ByteBuffer> parameters) { ThreadIdAndCpuTime threadIdAndCpuTime = new ThreadIdAndCpuTime(); return async(threadIdAndCpuTime, () -> { threadIdAndCpuTime.setup(); return executeUserDefined(protocolVersion, parameters); }); }