Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.facebook.presto.metadata;
 
 import org.joni.Regex;
 
 
 import java.util.List;
 import java.util.Set;
 
 import static com.facebook.presto.metadata.FunctionRegistry.operatorInfo;
 import static com.facebook.presto.spi.type.BigintType.BIGINT;
 import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature;
 import static com.facebook.presto.type.TypeUtils.resolveTypes;
 import static com.google.common.base.CaseFormat.LOWER_CAMEL;
 import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static java.lang.invoke.MethodHandles.lookup;
 import static java.util.Locale.ENGLISH;
 
 public class FunctionListBuilder
 {
     private static final Set<Class<?>> NULLABLE_ARGUMENT_TYPES = ImmutableSet.<Class<?>>of(Boolean.classLong.classDouble.classSlice.class);
 
     private static final Set<Class<?>> SUPPORTED_TYPES = ImmutableSet.of(
             long.class,
             Long.class,
             double.class,
             Double.class,
             Slice.class,
             boolean.class,
             Boolean.class,
             Pattern.class,
             Regex.class,
             JsonPath.class);
 
     private static final Set<Class<?>> SUPPORTED_RETURN_TYPES = ImmutableSet.of(
             long.class,
             double.class,
             Slice.class,
             boolean.class,
             int.class,
             Pattern.class,
             Regex.class,
             JsonPath.class);
 
     private final List<ParametricFunctionfunctions = new ArrayList<>();
     private final TypeManager typeManager;
 
     public FunctionListBuilder(TypeManager typeManager)
     {
         this. = checkNotNull(typeManager"typeManager is null");
     }
 
     public FunctionListBuilder window(String nameType returnTypeList<? extends TypeargumentTypesClass<? extends WindowFunctionfunctionClass)
     {
         WindowFunctionSupplier windowFunctionSupplier = new ReflectionWindowFunctionSupplier<>(
                new Signature(namereturnType.getTypeSignature(), Lists.transform(ImmutableList.copyOf(argumentTypes), Type::getTypeSignature)),
                functionClass);
        .add(new FunctionInfo(windowFunctionSupplier.getSignature(), windowFunctionSupplier.getDescription(), windowFunctionSupplier));
        return this;
    }
    {
        for (InternalAggregationFunction function : functions) {
            aggregate(function);
        }
        return this;
    }
    {
        String name = function.name();
        name = name.toLowerCase();
        String description = getDescription(function.getClass());
        Signature signature = new Signature(namefunction.getFinalType().getTypeSignature(), Lists.transform(ImmutableList.copyOf(function.getParameterTypes()), Type::getTypeSignature));
        .add(new FunctionInfo(signaturedescriptionfunction.getIntermediateType().getTypeSignature(), functionfunction.isApproximate()));
        return this;
    }
    public FunctionListBuilder aggregate(Class<?> aggregationDefinition)
    {
        .addAll(GenericAggregationFunctionFactory.fromAggregationDefinition(aggregationDefinition).listFunctions());
        return this;
    }
    public FunctionListBuilder scalar(Signature signatureMethodHandle functionboolean deterministicString descriptionboolean hiddenboolean nullableList<BooleannullableArguments)
    {
        .add(new FunctionInfo(signaturedescriptionhiddenfunctiondeterministicnullablenullableArguments));
        return this;
    }
    private FunctionListBuilder operator(OperatorType operatorTypeType returnTypeList<TypeparameterTypesMethodHandle functionboolean nullableList<BooleannullableArguments)
    {
        FunctionInfo operatorInfo = operatorInfo(operatorTypereturnType.getTypeSignature(), Lists.transform(parameterTypes, Type::getTypeSignature), functionnullablenullableArguments);
        .add(operatorInfo);
        return this;
    }
    public FunctionListBuilder scalar(Class<?> clazz)
    {
        try {
            boolean foundOne = false;
            for (Method method : clazz.getMethods()) {
                foundOne = processScalarFunction(method) || foundOne;
                foundOne = processScalarOperator(method) || foundOne;
            }
            checkArgument(foundOne"Expected class %s to contain at least one method annotated with @%s"clazz.getName(), ScalarFunction.class.getSimpleName());
        }
        catch (IllegalAccessException e) {
            throw Throwables.propagate(e);
        }
        return this;
    }
    public FunctionListBuilder functions(ParametricFunction ... parametricFunctions)
    {
        for (ParametricFunction parametricFunction : parametricFunctions) {
            function(parametricFunction);
        }
        return this;
    }
    public FunctionListBuilder function(ParametricFunction parametricFunction)
    {
        checkNotNull(parametricFunction"parametricFunction is null");
        .add(parametricFunction);
        return this;
    }
    private boolean processScalarFunction(Method method)
            throws IllegalAccessException
    {
        ScalarFunction scalarFunction = method.getAnnotation(ScalarFunction.class);
        if (scalarFunction == null) {
            return false;
        }
        checkValidMethod(method);
        MethodHandle methodHandle = lookup().unreflect(method);
        String name = scalarFunction.value();
        if (name.isEmpty()) {
            name = camelToSnake(method.getName());
        }
        SqlType returnTypeAnnotation = method.getAnnotation(SqlType.class);
        checkArgument(returnTypeAnnotation != null"Method %s return type does not have a @SqlType annotation"method);
        Type returnType = type(returnTypeAnnotation);
        Signature signature = new Signature(name.toLowerCase(), returnType.getTypeSignature(), Lists.transform(parameterTypes(method), Type::getTypeSignature));
        verifyMethodSignature(methodsignature.getReturnType(), signature.getArgumentTypes(), );
        List<BooleannullableArguments = getNullableArguments(method);
        scalar(signaturemethodHandlescalarFunction.deterministic(), getDescription(method), scalarFunction.hidden(), method.isAnnotationPresent(Nullable.class), nullableArguments);
        for (String alias : scalarFunction.alias()) {
            scalar(signature.withAlias(alias.toLowerCase()), methodHandlescalarFunction.deterministic(), getDescription(method), scalarFunction.hidden(), method.isAnnotationPresent(Nullable.class), nullableArguments);
        }
        return true;
    }
    private static Type type(TypeManager typeManagerSqlType explicitType)
    {
        Type type = typeManager.getType(parseTypeSignature(explicitType.value()));
        checkNotNull(type"No type found for '%s'"explicitType.value());
        return type;
    }
    private static List<TypeparameterTypes(TypeManager typeManagerMethod method)
    {
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        ImmutableList.Builder<Typetypes = ImmutableList.builder();
        for (int i = 0; i < method.getParameterTypes().lengthi++) {
            Class<?> clazz = method.getParameterTypes()[i];
            // skip session parameters
            if (clazz == ConnectorSession.class) {
                continue;
            }
            // find the explicit type annotation if present
            SqlType explicitType = null;
            for (Annotation annotation : parameterAnnotations[i]) {
                if (annotation instanceof SqlType) {
                    explicitType = (SqlTypeannotation;
                    break;
                }
            }
            checkArgument(explicitType != null"Method %s argument %s does not have a @SqlType annotation"methodi);
            types.add(type(typeManagerexplicitType));
        }
        return types.build();
    }
    private static void verifyMethodSignature(Method methodTypeSignature returnTypeNameList<TypeSignatureargumentTypeNamesTypeManager typeManager)
    {
        Type returnType = typeManager.getType(returnTypeName);
        checkNotNull(returnType"returnType is null");
        List<TypeargumentTypes = resolveTypes(argumentTypeNamestypeManager);
        checkArgument(Primitives.unwrap(method.getReturnType()) == returnType.getJavaType(),
                "Expected method %s return type to be %s (%s)",
                method,
                returnType.getJavaType().getName(),
                returnType);
        // skip Session argument
        Class<?>[] parameterTypes = method.getParameterTypes();
        Annotation[][] annotations = method.getParameterAnnotations();
        if (parameterTypes.length > 0 && parameterTypes[0] == ConnectorSession.class) {
            parameterTypes = Arrays.copyOfRange(parameterTypes, 1, parameterTypes.length);
            annotations = Arrays.copyOfRange(annotations, 1, annotations.length);
        }
        for (int i = 0; i < parameterTypes.lengthi++) {
            Class<?> actualType = parameterTypes[i];
            Type expectedType = argumentTypes.get(i);
            boolean nullable = !FluentIterable.from(Arrays.asList(annotations[i])).filter(Nullable.class).isEmpty();
            // Only allow boxing for functions that need to see nulls
            if (Primitives.isWrapperType(actualType)) {
                checkArgument(nullable"Method %s has parameter with type %s that is missing @Nullable"methodactualType);
            }
            if (nullable) {
                checkArgument(.contains(actualType), "Method %s has parameter type %s, but @Nullable is not supported on this type"methodactualType);
            }
            checkArgument(Primitives.unwrap(actualType) == expectedType.getJavaType(),
                    "Expected method %s parameter %s type to be %s (%s)",
                    method,
                    i,
                    expectedType.getJavaType().getName(),
                    expectedType);
        }
    }
    private static List<BooleangetNullableArguments(Method method)
    {
        List<BooleannullableArguments = new ArrayList<>();
        for (Annotation[] annotations : method.getParameterAnnotations()) {
            boolean nullable = false;
            boolean foundSqlType = false;
            for (Annotation annotation : annotations) {
                if (annotation instanceof Nullable) {
                    nullable = true;
                }
                if (annotation instanceof SqlType) {
                    foundSqlType = true;
                }
            }
            // Check that this is a real argument. For example, some functions take ConnectorSession which isn't a SqlType
            if (foundSqlType) {
                nullableArguments.add(nullable);
            }
        }
        return nullableArguments;
    }
    private boolean processScalarOperator(Method method)
            throws IllegalAccessException
    {
        ScalarOperator scalarOperator = method.getAnnotation(ScalarOperator.class);
        if (scalarOperator == null) {
            return false;
        }
        checkValidMethod(method);
        MethodHandle methodHandle = lookup().unreflect(method);
        OperatorType operatorType = scalarOperator.value();
        List<TypeparameterTypes = parameterTypes(method);
        Type returnType;
        if (operatorType == .) {
            // todo hack for hashCode... should be int
            returnType = ;
        }
        else {
            SqlType explicitType = method.getAnnotation(SqlType.class);
            checkArgument(explicitType != null"Method %s return type does not have a @SqlType annotation"method);
            returnType = type(explicitType);
            verifyMethodSignature(methodreturnType.getTypeSignature(), Lists.transform(parameterTypes, Type::getTypeSignature), );
        }
        List<BooleannullableArguments = getNullableArguments(method);
        operator(operatorTypereturnTypeparameterTypesmethodHandlemethod.isAnnotationPresent(Nullable.class), nullableArguments);
        return true;
    }
    private static String getDescription(AnnotatedElement annotatedElement)
    {
        Description description = annotatedElement.getAnnotation(Description.class);
        return (description == null) ? null : description.value();
    }
    private static String camelToSnake(String name)
    {
        return .to(name);
    }
    private static void checkValidMethod(Method method)
    {
        String message = "@ScalarFunction method %s is not valid: ";
        checkArgument(Modifier.isStatic(method.getModifiers()), message + "must be static"method);
        checkArgument(.contains(Primitives.unwrap(method.getReturnType())), message + "return type not supported"method);
        if (method.getAnnotation(Nullable.class) != null) {
            checkArgument(!method.getReturnType().isPrimitive(), message + "annotated with @Nullable but has primitive return type"method);
        }
        else {
            checkArgument(!Primitives.isWrapperType(method.getReturnType()), "not annotated with @Nullable but has boxed primitive return type"method);
        }
        for (Class<?> type : getParameterTypes(method.getParameterTypes())) {
            checkArgument(.contains(type), message + "parameter type [%s] not supported"methodtype.getName());
        }
    }
    private static List<Class<?>> getParameterTypes(Class<?>... types)
    {
        ImmutableList<Class<?>> parameterTypes = ImmutableList.copyOf(types);
        if (!parameterTypes.isEmpty() && parameterTypes.get(0) == ConnectorSession.class) {
            parameterTypes = parameterTypes.subList(1, parameterTypes.size());
        }
        return parameterTypes;
    }
    {
        return ImmutableList.copyOf();
    }
New to GrepCode? Check out our FAQ X