@Override public void addFunctionsTo(List<Function> functions) { functions.add(this); if (stateFunction != null) { stateFunction.addFunctionsTo(functions); if (finalFunction != null) finalFunction.addFunctionsTo(functions); } }
private static ByteBuffer executeInternal(ProtocolVersion protocolVersion, ScalarFunction fun, List<ByteBuffer> params) throws InvalidRequestException { ByteBuffer result = fun.execute(protocolVersion, params); try { // Check the method didn't lied on it's declared return type if (result != null) fun.returnType().validate(result); return result; } catch (MarshalException e) { throw new RuntimeException(String.format("Return of function %s (%s) is not a valid value for its declared return type %s", fun, ByteBufferUtil.bytesToHex(result), fun.returnType().asCQL3Type()), e); } }
public ByteBuffer bindAndGet(QueryOptions options) throws InvalidRequestException { List<ByteBuffer> buffers = new ArrayList<>(terms.size()); for (Term t : terms) { ByteBuffer functionArg = t.bindAndGet(options); RequestValidations.checkBindValueSet(functionArg, "Invalid unset value for argument in call to function %s", fun.name().name); buffers.add(functionArg); } return executeInternal(options.getProtocolVersion(), fun, buffers); }
public Term prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException { Function fun = FunctionResolver.get(keyspace, name, terms, receiver.ksName, receiver.cfName, receiver.type); if (fun == null) throw new InvalidRequestException(String.format("Unknown function %s called", name)); if (fun.isAggregate()) throw new InvalidRequestException("Aggregation function are not supported in the where clause"); ScalarFunction scalarFun = (ScalarFunction) fun; // Functions.get() will complain if no function "name" type check with the provided arguments. // We still have to validate that the return type matches however if (!scalarFun.testAssignment(keyspace, receiver).isAssignable()) throw new InvalidRequestException(String.format("Type error: cannot assign result of function %s (type %s) to %s (type %s)", scalarFun.name(), scalarFun.returnType().asCQL3Type(), receiver.name, receiver.type.asCQL3Type())); if (fun.argTypes().size() != terms.size()) throw new InvalidRequestException(String.format("Incorrect number of arguments specified for function %s (expected %d, found %d)", fun, fun.argTypes().size(), terms.size())); List<Term> parameters = new ArrayList<>(terms.size()); for (int i = 0; i < terms.size(); i++) { Term t = terms.get(i).prepare(keyspace, FunctionResolver.makeArgSpec(receiver.ksName, receiver.cfName, scalarFun, i)); parameters.add(t); } return new FunctionCall(scalarFun, parameters); }
stateFunction = (ScalarFunction)f; AbstractType<?> stateReturnType = stateFunction.returnType(); if (!stateReturnType.equals(stateType)) throw new InvalidRequestException("State function " + stateFuncSig(stateFunction.name(), stateTypeRaw, argRawTypes) + " return type must be the same as the first argument type - check STYPE, argument and return types"); throw new InvalidRequestException("Final function " + finalFunc + '(' + stateTypeRaw + ") does not exist or is not a scalar function"); finalFunction = (ScalarFunction) f; returnType = finalFunction.returnType();
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())); }
public ByteBuffer getOutput(ProtocolVersion protocolVersion) throws InvalidRequestException { for (int i = 0, m = argSelectors.size(); i < m; i++) { Selector s = argSelectors.get(i); setArg(i, s.getOutput(protocolVersion)); s.reset(); } return fun.execute(protocolVersion, args()); }
public UDAggregate(FunctionName name, List<AbstractType<?>> argTypes, AbstractType<?> returnType, ScalarFunction stateFunc, ScalarFunction finalFunc, ByteBuffer initcond) { super(name, argTypes, returnType); this.stateFunction = stateFunc; this.finalFunction = finalFunc; this.stateType = stateFunc != null ? stateFunc.returnType() : null; this.stateTypeCodec = stateType != null ? UDHelper.codecFor(UDHelper.driverType(stateType)) : null; this.returnTypeCodec = returnType != null ? UDHelper.codecFor(UDHelper.driverType(returnType)) : null; this.initcond = initcond; }
public Term prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException { Function fun = FunctionResolver.get(keyspace, name, terms, receiver.ksName, receiver.cfName, receiver.type); if (fun == null) throw new InvalidRequestException(String.format("Unknown function %s called", name)); if (fun.isAggregate()) throw new InvalidRequestException("Aggregation function are not supported in the where clause"); ScalarFunction scalarFun = (ScalarFunction) fun; // Functions.get() will complain if no function "name" type check with the provided arguments. // We still have to validate that the return type matches however if (!scalarFun.testAssignment(keyspace, receiver).isAssignable()) throw new InvalidRequestException(String.format("Type error: cannot assign result of function %s (type %s) to %s (type %s)", scalarFun.name(), scalarFun.returnType().asCQL3Type(), receiver.name, receiver.type.asCQL3Type())); if (fun.argTypes().size() != terms.size()) throw new InvalidRequestException(String.format("Incorrect number of arguments specified for function %s (expected %d, found %d)", fun, fun.argTypes().size(), terms.size())); List<Term> parameters = new ArrayList<>(terms.size()); for (int i = 0; i < terms.size(); i++) { Term t = terms.get(i).prepare(keyspace, FunctionResolver.makeArgSpec(receiver.ksName, receiver.cfName, scalarFun, i)); parameters.add(t); } return new FunctionCall(scalarFun, parameters); }
stateFunction = (ScalarFunction)f; AbstractType<?> stateReturnType = stateFunction.returnType(); if (!stateReturnType.equals(stateType)) throw new InvalidRequestException("State function " + stateFuncSig(stateFunction.name(), stateTypeRaw, argRawTypes) + " return type must be the same as the first argument type - check STYPE, argument and return types"); throw new InvalidRequestException("Final function " + finalFunc + '(' + stateTypeRaw + ") does not exist or is not a scalar function"); finalFunction = (ScalarFunction) f; returnType = finalFunction.returnType();
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())); }
public ByteBuffer getOutput(ProtocolVersion protocolVersion) throws InvalidRequestException { for (int i = 0, m = argSelectors.size(); i < m; i++) { Selector s = argSelectors.get(i); setArg(i, s.getOutput(protocolVersion)); s.reset(); } return fun.execute(protocolVersion, args()); }
public UDAggregate(FunctionName name, List<AbstractType<?>> argTypes, AbstractType<?> returnType, ScalarFunction stateFunc, ScalarFunction finalFunc, ByteBuffer initcond) { super(name, argTypes, returnType); this.stateFunction = stateFunc; this.finalFunction = finalFunc; this.stateType = stateFunc != null ? stateFunc.returnType() : null; this.stateTypeCodec = stateType != null ? UDHelper.codecFor(UDHelper.driverType(stateType)) : null; this.returnTypeCodec = returnType != null ? UDHelper.codecFor(UDHelper.driverType(returnType)) : null; this.initcond = initcond; }
public Term prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException { Function fun = FunctionResolver.get(keyspace, name, terms, receiver.ksName, receiver.cfName, receiver.type); if (fun == null) throw new InvalidRequestException(String.format("Unknown function %s called", name)); if (fun.isAggregate()) throw new InvalidRequestException("Aggregation function are not supported in the where clause"); ScalarFunction scalarFun = (ScalarFunction) fun; // Functions.get() will complain if no function "name" type check with the provided arguments. // We still have to validate that the return type matches however if (!scalarFun.testAssignment(keyspace, receiver).isAssignable()) throw new InvalidRequestException(String.format("Type error: cannot assign result of function %s (type %s) to %s (type %s)", scalarFun.name(), scalarFun.returnType().asCQL3Type(), receiver.name, receiver.type.asCQL3Type())); if (fun.argTypes().size() != terms.size()) throw new InvalidRequestException(String.format("Incorrect number of arguments specified for function %s (expected %d, found %d)", fun, fun.argTypes().size(), terms.size())); List<Term> parameters = new ArrayList<>(terms.size()); for (int i = 0; i < terms.size(); i++) { Term t = terms.get(i).prepare(keyspace, FunctionResolver.makeArgSpec(receiver.ksName, receiver.cfName, scalarFun, i)); parameters.add(t); } return new FunctionCall(scalarFun, parameters); }
private static ByteBuffer executeInternal(ProtocolVersion protocolVersion, ScalarFunction fun, List<ByteBuffer> params) throws InvalidRequestException { ByteBuffer result = fun.execute(protocolVersion, params); try { // Check the method didn't lied on it's declared return type if (result != null) fun.returnType().validate(result); return result; } catch (MarshalException e) { throw new RuntimeException(String.format("Return of function %s (%s) is not a valid value for its declared return type %s", fun, ByteBufferUtil.bytesToHex(result), fun.returnType().asCQL3Type()), e); } }
stateFunction = (ScalarFunction)f; AbstractType<?> stateReturnType = stateFunction.returnType(); if (!stateReturnType.equals(stateType)) throw new InvalidRequestException("State function " + stateFuncSig(stateFunction.name(), stateTypeRaw, argRawTypes) + " return type must be the same as the first argument type - check STYPE, argument and return types"); throw new InvalidRequestException("Final function " + finalFunc + '(' + stateTypeRaw + ") does not exist or is not a scalar function"); finalFunction = (ScalarFunction) f; returnType = finalFunction.returnType();
public ByteBuffer bindAndGet(QueryOptions options) throws InvalidRequestException { List<ByteBuffer> buffers = new ArrayList<>(terms.size()); for (Term t : terms) { ByteBuffer functionArg = t.bindAndGet(options); RequestValidations.checkBindValueSet(functionArg, "Invalid unset value for argument in call to function %s", fun.name().name); buffers.add(functionArg); } return executeInternal(options.getProtocolVersion(), fun, buffers); }
@Override public void addFunctionsTo(List<Function> functions) { functions.add(this); if (stateFunction != null) { stateFunction.addFunctionsTo(functions); if (finalFunction != null) finalFunction.addFunctionsTo(functions); } }
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 AggregateFunction)) throw new InvalidRequestException(String.format("Aggregate %s can only replace an aggregate", old)); // Means we're replacing the function. We still need to validate that 1) it's not a native function and 2) that the return type // matches (or that could break existing code badly) if (old.isNative()) throw new InvalidRequestException(String.format("Cannot replace native aggregate %s", old)); if (!old.returnType().isValueCompatibleWith(returnType)) throw new InvalidRequestException(String.format("Cannot replace aggregate %s, the new return type %s is not compatible with the return type %s of existing function", functionName, returnType.asCQL3Type(), old.returnType().asCQL3Type())); } if (!stateFunction.isCalledOnNullInput() && initcond == null) throw new InvalidRequestException(String.format("Cannot create aggregate %s without INITCOND because state function %s does not accept 'null' arguments", functionName, stateFunc)); UDAggregate udAggregate = new UDAggregate(functionName, argTypes, returnType, stateFunction, finalFunction, initcond); MigrationManager.announceNewAggregate(udAggregate, isLocalOnly); return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.AGGREGATE, udAggregate.name().keyspace, udAggregate.name().name, AbstractType.asCQLTypeStringList(udAggregate.argTypes())); }
public ByteBuffer getOutput(ProtocolVersion protocolVersion) throws InvalidRequestException { for (int i = 0, m = argSelectors.size(); i < m; i++) { Selector s = argSelectors.get(i); setArg(i, s.getOutput(protocolVersion)); s.reset(); } return fun.execute(protocolVersion, args()); }