public MethodsGroupBuilder methods(List<String> methodNames) { requireNonNull(methodNames, "methodNames is null"); checkArgument(!methodNames.isEmpty(), "methods list is empty"); methodNames.forEach(methodName -> this.methodWithExplicitJavaTypes(methodName, nCopies(signature.getArgumentTypes().size(), Optional.empty()))); return this; }
@Override public final WindowFunction createWindowFunction(List<Integer> argumentChannels) { requireNonNull(argumentChannels, "inputs is null"); checkArgument(argumentChannels.size() == signature.getArgumentTypes().size(), "Expected %s arguments for function %s, but got %s", signature.getArgumentTypes().size(), signature.getName(), argumentChannels.size()); return newWindowFunction(argumentChannels); }
public ReflectionWindowFunctionSupplier(Signature signature, Class<T> type) { super(signature, getDescription(requireNonNull(type, "type is null"))); try { if (signature.getArgumentTypes().isEmpty()) { constructor = type.getConstructor(); } else { constructor = type.getConstructor(List.class); } } catch (NoSuchMethodException e) { throw new RuntimeException(e); } }
@Override protected T newWindowFunction(List<Integer> inputs) { try { if (getSignature().getArgumentTypes().isEmpty()) { return constructor.newInstance(); } else { return constructor.newInstance(inputs); } } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } }
private boolean onlyCastsUnknown(ApplicableFunction applicableFunction, List<Type> actualParameters) { List<Type> boundTypes = resolveTypes(applicableFunction.getBoundSignature().getArgumentTypes(), typeManager); checkState(actualParameters.size() == boundTypes.size(), "type lists are of different lengths"); for (int i = 0; i < actualParameters.size(); i++) { if (!boundTypes.get(i).equals(actualParameters.get(i)) && actualParameters.get(i) != UNKNOWN) { return false; } } return true; }
/** * Example of not allowed literal variable usages across typeSignatures: * <p><ul> * <li>x used in different base types: char(x) and varchar(x) * <li>x used in different positions of the same base type: decimal(x,y) and decimal(z,x) * <li>p used in combination with different literals, types, or literal variables: decimal(p,s1) and decimal(p,s2) * </ul> */ private static void checkNoLiteralVariableUsageAcrossTypes(Signature declaredSignature) { Map<String, TypeSignature> existingUsages = new HashMap<>(); for (TypeSignature parameter : declaredSignature.getArgumentTypes()) { checkNoLiteralVariableUsageAcrossTypes(parameter, existingUsages); } }
public boolean areTypesAssignable(Signature boundSignature, BoundVariables variables, TypeManager typeManager, FunctionRegistry functionRegistry) { checkState(argumentNativeContainerTypes.size() == boundSignature.getArgumentTypes().size(), "Number of argument assigned to AggregationImplementation is different than number parsed from annotations."); // TODO specialized functions variants support is missing here for (int i = 0; i < boundSignature.getArgumentTypes().size(); i++) { Class<?> argumentType = typeManager.getType(boundSignature.getArgumentTypes().get(i)).getJavaType(); Class<?> methodDeclaredType = argumentNativeContainerTypes.get(i).getJavaType(); boolean isCurrentBlockPosition = argumentNativeContainerTypes.get(i).isBlockPosition(); if (isCurrentBlockPosition && Block.class.isAssignableFrom(methodDeclaredType)) { continue; } if (!isCurrentBlockPosition && argumentType.isAssignableFrom(methodDeclaredType)) { continue; } return false; } return true; }
public ChoiceBuilder implementation(Function<MethodsGroupBuilder, MethodsGroupBuilder> methodsGroupSpecification) { // if the argumentProperties is not set yet. We assume it is set to the default value. if (argumentProperties == null) { argumentProperties = nCopies(signature.getArgumentTypes().size(), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); } // if the returnPlaceConvention is not set yet. We assume it is set to the default value. if (returnPlaceConvention == null) { returnPlaceConvention = ReturnPlaceConvention.STACK; } MethodsGroupBuilder methodsGroupBuilder = new MethodsGroupBuilder(clazz, signature, argumentProperties); methodsGroupSpecification.apply(methodsGroupBuilder); methodsGroups.add(methodsGroupBuilder.build()); return this; }
private MethodHandle applyExtraParameters(Method matchingMethod, List<Object> extraParameters, List<ArgumentProperty> argumentProperties) { Signature signature = getSignature(); int expectedArgumentsCount = signature.getArgumentTypes().size() + getNullFlagsCount(argumentProperties) + getBlockPositionCount(argumentProperties) + extraParameters.size(); int matchingMethodArgumentCount = matchingMethod.getParameterCount(); checkState(matchingMethodArgumentCount == expectedArgumentsCount, "method %s has invalid number of arguments: %s (should have %s)", matchingMethod.getName(), matchingMethodArgumentCount, expectedArgumentsCount); MethodHandle matchingMethodHandle = Reflection.methodHandle(matchingMethod); matchingMethodHandle = MethodHandles.insertArguments( matchingMethodHandle, matchingMethodArgumentCount - extraParameters.size(), extraParameters.toArray()); return matchingMethodHandle; }
@VisibleForTesting public static ParametricAggregation parseFunctionDefinitionWithTypesConstraint(Class<?> clazz, TypeSignature returnType, List<TypeSignature> argumentTypes) { requireNonNull(returnType, "returnType is null"); requireNonNull(argumentTypes, "argumentTypes is null"); for (ParametricAggregation aggregation : parseFunctionDefinitions(clazz)) { if (aggregation.getSignature().getReturnType().equals(returnType) && aggregation.getSignature().getArgumentTypes().equals(argumentTypes)) { return aggregation; } } throw new IllegalArgumentException(String.format("No method with return type %s and arguments %s", returnType, argumentTypes)); }
public Signature withAlias(String name) { return new Signature(name, kind, typeVariableConstraints, longVariableConstraints, getReturnType(), getArgumentTypes(), variableArity); }
public void addImplementation(T implementation) { if (implementation.getSignature().getTypeVariableConstraints().isEmpty() && implementation.getSignature().getArgumentTypes().stream().noneMatch(TypeSignature::isCalculated) && !implementation.getSignature().getReturnType().isCalculated()) { exactImplementations.put(implementation.getSignature(), implementation); } else if (implementation.hasSpecializedTypeParameters()) { specializedImplementations.add(implementation); } else { genericImplementations.add(implementation); } }
@Override public InternalAggregationFunction specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { Type type = typeManager.getType(getOnlyElement(applyBoundVariables(getSignature().getArgumentTypes(), boundVariables))); return generateAggregation(type); }
private static boolean isCountOverConstant(AggregationNode.Aggregation aggregation, Assignments inputs) { Signature signature = aggregation.getSignature(); if (!signature.getName().equals("count") || signature.getArgumentTypes().size() != 1) { return false; } Expression argument = aggregation.getCall().getArguments().get(0); if (argument instanceof SymbolReference) { argument = inputs.get(Symbol.from(argument)); } return argument instanceof Literal && !(argument instanceof NullLiteral); } }
@Override public MethodHandle resolve(BoundVariables boundVariables, TypeManager typeManager, FunctionRegistry functionRegistry) { Signature signature = applyBoundVariables(this.signature, boundVariables, this.signature.getArgumentTypes().size()); if (invocationConvention.isPresent()) { return functionRegistry.getFunctionInvokerProvider().createFunctionInvoker(signature, invocationConvention).methodHandle(); } else { return functionRegistry.getScalarFunctionImplementation(signature).getMethodHandle(); } }
/** * One method is more specific than another if invocation handled by the first method could be passed on to the other one */ private boolean isMoreSpecificThan(ApplicableFunction left, ApplicableFunction right) { List<TypeSignatureProvider> resolvedTypes = fromTypeSignatures(left.getBoundSignature().getArgumentTypes()); Optional<BoundVariables> boundVariables = new SignatureBinder(typeManager, right.getDeclaredSignature(), true) .bindVariables(resolvedTypes); return boundVariables.isPresent(); }
private ColumnStatisticsAggregation createAggregation(QualifiedName functionName, SymbolReference input, Type inputType, Type outputType) { Signature signature = metadata.getFunctionRegistry().resolveFunction(functionName, TypeSignatureProvider.fromTypes(ImmutableList.of(inputType))); Type resolvedType = metadata.getType(getOnlyElement(signature.getArgumentTypes())); verify(resolvedType.equals(inputType), "resolved function input type does not match the input type: %s != %s", resolvedType, inputType); return new ColumnStatisticsAggregation( new AggregationNode.Aggregation( new FunctionCall(functionName, ImmutableList.of(input)), signature, Optional.empty()), outputType); }
@Override public InternalAggregationFunction specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { Type inputType = typeManager.getType(getOnlyElement(applyBoundVariables(getSignature().getArgumentTypes(), boundVariables))); Type outputType = typeManager.getType(applyBoundVariables(getSignature().getReturnType(), boundVariables)); return generateAggregation(inputType, outputType); }
@Test public void testMagicLiteralFunction() { Signature signature = getMagicLiteralFunctionSignature(TIMESTAMP_WITH_TIME_ZONE); assertEquals(signature.getName(), "$literal$timestamp with time zone"); assertEquals(signature.getArgumentTypes(), ImmutableList.of(parseTypeSignature(StandardTypes.BIGINT))); assertEquals(signature.getReturnType().getBase(), StandardTypes.TIMESTAMP_WITH_TIME_ZONE); TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); Signature function = registry.resolveFunction(QualifiedName.of(signature.getName()), fromTypeSignatures(signature.getArgumentTypes())); assertEquals(function.getArgumentTypes(), ImmutableList.of(parseTypeSignature(StandardTypes.BIGINT))); assertEquals(signature.getReturnType().getBase(), StandardTypes.TIMESTAMP_WITH_TIME_ZONE); }
@Test public void testIdentityCast() { TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); Signature exactOperator = registry.getCoercion(HYPER_LOG_LOG, HYPER_LOG_LOG); assertEquals(exactOperator.getName(), mangleOperatorName(OperatorType.CAST.name())); assertEquals(transform(exactOperator.getArgumentTypes(), Functions.toStringFunction()), ImmutableList.of(StandardTypes.HYPER_LOG_LOG)); assertEquals(exactOperator.getReturnType().getBase(), StandardTypes.HYPER_LOG_LOG); }