// 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) throws InvalidRequestException { if (providedArgs.size() != fun.argTypes().size()) throw new InvalidRequestException( String.format( "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); // If the concrete argument is a bind variables, it can have any type. // 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 new InvalidRequestException( String.format( "Type error: %s cannot be passed as argument %d of function %s of type %s", provided, i, fun.name(), expected.type.asCQL3Type())); } }
private static void declare(Function fun) { synchronized (declared) { List<Function> functions = declared.get(fun.name()); if (functions == null) { functions = new CopyOnWriteArrayList<>(); List<Function> existing = declared.putIfAbsent(fun.name(), functions); if (existing != null) functions = existing; } functions.add(fun); } }
public static ColumnSpecification makeArgSpec( String receiverKs, String receiverCf, Function fun, int i) { return new ColumnSpecification( receiverKs, receiverCf, new ColumnIdentifier("arg" + i + '(' + fun.name().toString().toLowerCase() + ')', true), fun.argTypes().get(i)); }