// 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())); } }
public static List<Function> getReferencesTo(Function old) { List<Function> references = new ArrayList<>(); for (List<Function> functions : declared.values()) for (Function function : functions) if (function.hasReferenceTo(old)) references.add(function); return references; }
public static Function find(FunctionName name, List<AbstractType<?>> argTypes) { assert name.hasKeyspace() : "function name not fully qualified"; for (Function f : find(name)) { if (typeEquals(f.argTypes(), argTypes)) return f; } return null; }
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)); }
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); } }
// Same remarks than for addFunction public static void removeFunction(FunctionName name, List<AbstractType<?>> argTypes) { assert name.hasKeyspace() : "function name " + name + " not fully qualified"; synchronized (declared) { List<Function> functions = find(name); for (int i = 0; i < functions.size(); i++) { Function f = functions.get(i); if (!typeEquals(f.argTypes(), argTypes)) continue; assert !f.isNative(); functions.remove(i); if (functions.isEmpty()) declared.remove(name); return; } } }
private static AssignmentTestable.TestResult matchAguments( String keyspace, Function fun, List<? extends AssignmentTestable> providedArgs, String receiverKs, String receiverCf) { if (providedArgs.size() != fun.argTypes().size()) return AssignmentTestable.TestResult.NOT_ASSIGNABLE; // It's an exact match if all are exact match, but is not assignable as soon as any is non // assignable. AssignmentTestable.TestResult res = AssignmentTestable.TestResult.EXACT_MATCH; for (int i = 0; i < providedArgs.size(); i++) { AssignmentTestable provided = providedArgs.get(i); if (provided == null) { res = AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE; continue; } ColumnSpecification expected = makeArgSpec(receiverKs, receiverCf, fun, i); AssignmentTestable.TestResult argRes = provided.testAssignment(keyspace, expected); if (argRes == AssignmentTestable.TestResult.NOT_ASSIGNABLE) return AssignmentTestable.TestResult.NOT_ASSIGNABLE; if (argRes == AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE) res = AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE; } return res; }