Search in sources :

Example 16 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method createTypeInfoFromFactory.

/**
	 * Creates type information using a factory if for this type or super types. Returns null otherwise.
	 */
@SuppressWarnings("unchecked")
private <IN1, IN2, OUT> TypeInformation<OUT> createTypeInfoFromFactory(Type t, ArrayList<Type> typeHierarchy, TypeInformation<IN1> in1Type, TypeInformation<IN2> in2Type) {
    final ArrayList<Type> factoryHierarchy = new ArrayList<>(typeHierarchy);
    final TypeInfoFactory<? super OUT> factory = getClosestFactory(factoryHierarchy, t);
    if (factory == null) {
        return null;
    }
    final Type factoryDefiningType = factoryHierarchy.get(factoryHierarchy.size() - 1);
    // infer possible type parameters from input
    final Map<String, TypeInformation<?>> genericParams;
    if (factoryDefiningType instanceof ParameterizedType) {
        genericParams = new HashMap<>();
        final ParameterizedType paramDefiningType = (ParameterizedType) factoryDefiningType;
        final Type[] args = typeToClass(paramDefiningType).getTypeParameters();
        final TypeInformation<?>[] subtypeInfo = createSubTypesInfo(t, paramDefiningType, factoryHierarchy, in1Type, in2Type, true);
        assert subtypeInfo != null;
        for (int i = 0; i < subtypeInfo.length; i++) {
            genericParams.put(args[i].toString(), subtypeInfo[i]);
        }
    } else {
        genericParams = Collections.emptyMap();
    }
    final TypeInformation<OUT> createdTypeInfo = (TypeInformation<OUT>) factory.createTypeInfo(t, genericParams);
    if (createdTypeInfo == null) {
        throw new InvalidTypesException("TypeInfoFactory returned invalid TypeInformation 'null'");
    }
    return createdTypeInfo;
}
Also used : ArrayList(java.util.ArrayList) TypeInformation(org.apache.flink.api.common.typeinfo.TypeInformation) ParameterizedType(java.lang.reflect.ParameterizedType) GenericArrayType(java.lang.reflect.GenericArrayType) TypeExtractionUtils.isClassType(org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType) Type(java.lang.reflect.Type) CompositeType(org.apache.flink.api.common.typeutils.CompositeType) ParameterizedType(java.lang.reflect.ParameterizedType) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException)

Example 17 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method validateInputContainsExecutable.

private static void validateInputContainsExecutable(LambdaExecutable exec, TypeInformation<?> typeInfo) {
    List<Method> methods = getAllDeclaredMethods(typeInfo.getTypeClass());
    for (Method method : methods) {
        if (exec.executablesEquals(method)) {
            return;
        }
    }
    Constructor<?>[] constructors = typeInfo.getTypeClass().getDeclaredConstructors();
    for (Constructor<?> constructor : constructors) {
        if (exec.executablesEquals(constructor)) {
            return;
        }
    }
    throw new InvalidTypesException("Type contains no executable '" + exec.getName() + "'.");
}
Also used : Constructor(java.lang.reflect.Constructor) Method(java.lang.reflect.Method) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException)

Example 18 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method getBinaryOperatorReturnType.

/**
	 * Returns the binary operator's return type.
	 *
	 * @param function Function to extract the return type from
	 * @param baseClass Base class of the function
	 * @param inputTypeArgumentIndex Index of the type argument of function's first parameter
	 *                               specifying the input type if it is wrapped (Iterable, Map,
	 *                               etc.). Otherwise -1.
	 * @param outputTypeArgumentIndex Index of the type argument of functions second parameter
	 *                                specifying the output type if it is wrapped in a Collector.
	 *                                Otherwise -1.
	 * @param in1Type Type of the left side input elements (In case of an iterable, it is the element type)
	 * @param in2Type Type of the right side input elements (In case of an iterable, it is the element type)
	 * @param functionName Function name
	 * @param allowMissing Can the type information be missing
	 * @param <IN1> Left side input type
	 * @param <IN2> Right side input type
	 * @param <OUT> Output type
	 * @return TypeInformation of the return type of the function
	 */
@SuppressWarnings("unchecked")
@PublicEvolving
public static <IN1, IN2, OUT> TypeInformation<OUT> getBinaryOperatorReturnType(Function function, Class<?> baseClass, int inputTypeArgumentIndex, int outputTypeArgumentIndex, TypeInformation<IN1> in1Type, TypeInformation<IN2> in2Type, String functionName, boolean allowMissing) {
    try {
        final LambdaExecutable exec;
        try {
            exec = checkAndExtractLambda(function);
        } catch (TypeExtractionException e) {
            throw new InvalidTypesException("Internal error occurred.", e);
        }
        if (exec != null) {
            // check for lambda type erasure
            validateLambdaGenericParameters(exec);
            // parameters must be accessed from behind, since JVM can add additional parameters e.g. when using local variables inside lambda function
            final int paramLen = exec.getParameterTypes().length - 1;
            final Type input1 = (outputTypeArgumentIndex >= 0) ? exec.getParameterTypes()[paramLen - 2] : exec.getParameterTypes()[paramLen - 1];
            final Type input2 = (outputTypeArgumentIndex >= 0) ? exec.getParameterTypes()[paramLen - 1] : exec.getParameterTypes()[paramLen];
            validateInputType((inputTypeArgumentIndex >= 0) ? extractTypeArgument(input1, inputTypeArgumentIndex) : input1, in1Type);
            validateInputType((inputTypeArgumentIndex >= 0) ? extractTypeArgument(input2, inputTypeArgumentIndex) : input2, in2Type);
            if (function instanceof ResultTypeQueryable) {
                return ((ResultTypeQueryable<OUT>) function).getProducedType();
            }
            return new TypeExtractor().privateCreateTypeInfo((outputTypeArgumentIndex >= 0) ? extractTypeArgument(exec.getParameterTypes()[paramLen], outputTypeArgumentIndex) : exec.getReturnType(), in1Type, in2Type);
        } else {
            validateInputType(baseClass, function.getClass(), 0, in1Type);
            validateInputType(baseClass, function.getClass(), 1, in2Type);
            if (function instanceof ResultTypeQueryable) {
                return ((ResultTypeQueryable<OUT>) function).getProducedType();
            }
            return new TypeExtractor().privateCreateTypeInfo(baseClass, function.getClass(), 2, in1Type, in2Type);
        }
    } catch (InvalidTypesException e) {
        if (allowMissing) {
            return (TypeInformation<OUT>) new MissingTypeInfo(functionName != null ? functionName : function.toString(), e);
        } else {
            throw e;
        }
    }
}
Also used : GenericArrayType(java.lang.reflect.GenericArrayType) TypeExtractionUtils.isClassType(org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType) Type(java.lang.reflect.Type) CompositeType(org.apache.flink.api.common.typeutils.CompositeType) ParameterizedType(java.lang.reflect.ParameterizedType) LambdaExecutable(org.apache.flink.api.java.typeutils.TypeExtractionUtils.LambdaExecutable) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) PublicEvolving(org.apache.flink.annotation.PublicEvolving)

Example 19 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class TypeExtractor method createTypeInfoFromInput.

/**
	 * Finds the type information to a type variable.
	 *
	 * It solve the following:
	 *
	 * Return the type information for "returnTypeVar" given that "inType" has type information "inTypeInfo".
	 * Thus "inType" must contain "returnTypeVar" in a "inputTypeHierarchy", otherwise null is returned.
	 */
@SuppressWarnings({ "unchecked", "rawtypes" })
private <IN1> TypeInformation<?> createTypeInfoFromInput(TypeVariable<?> returnTypeVar, ArrayList<Type> inputTypeHierarchy, Type inType, TypeInformation<IN1> inTypeInfo) {
    TypeInformation<?> info = null;
    // use a factory to find corresponding type information to type variable
    final ArrayList<Type> factoryHierarchy = new ArrayList<>(inputTypeHierarchy);
    final TypeInfoFactory<?> factory = getClosestFactory(factoryHierarchy, inType);
    if (factory != null) {
        // the type that defines the factory is last in factory hierarchy
        final Type factoryDefiningType = factoryHierarchy.get(factoryHierarchy.size() - 1);
        // defining type has generics, the factory need to be asked for a mapping of subtypes to type information
        if (factoryDefiningType instanceof ParameterizedType) {
            final Type[] typeParams = typeToClass(factoryDefiningType).getTypeParameters();
            final Type[] actualParams = ((ParameterizedType) factoryDefiningType).getActualTypeArguments();
            // go thru all elements and search for type variables
            for (int i = 0; i < actualParams.length; i++) {
                final Map<String, TypeInformation<?>> componentInfo = inTypeInfo.getGenericParameters();
                final String typeParamName = typeParams[i].toString();
                if (!componentInfo.containsKey(typeParamName) || componentInfo.get(typeParamName) == null) {
                    throw new InvalidTypesException("TypeInformation '" + inTypeInfo.getClass().getSimpleName() + "' does not supply a mapping of TypeVariable '" + typeParamName + "' to corresponding TypeInformation. " + "Input type inference can only produce a result with this information. " + "Please implement method 'TypeInformation.getGenericParameters()' for this.");
                }
                info = createTypeInfoFromInput(returnTypeVar, factoryHierarchy, actualParams[i], componentInfo.get(typeParamName));
                if (info != null) {
                    break;
                }
            }
        }
    } else // the input is a type variable
    if (sameTypeVars(inType, returnTypeVar)) {
        return inTypeInfo;
    } else if (inType instanceof TypeVariable) {
        Type resolvedInType = materializeTypeVariable(inputTypeHierarchy, (TypeVariable<?>) inType);
        if (resolvedInType != inType) {
            info = createTypeInfoFromInput(returnTypeVar, inputTypeHierarchy, resolvedInType, inTypeInfo);
        }
    } else // input is an array
    if (inType instanceof GenericArrayType) {
        TypeInformation<?> componentInfo = null;
        if (inTypeInfo instanceof BasicArrayTypeInfo) {
            componentInfo = ((BasicArrayTypeInfo<?, ?>) inTypeInfo).getComponentInfo();
        } else if (inTypeInfo instanceof PrimitiveArrayTypeInfo) {
            componentInfo = BasicTypeInfo.getInfoFor(inTypeInfo.getTypeClass().getComponentType());
        } else if (inTypeInfo instanceof ObjectArrayTypeInfo) {
            componentInfo = ((ObjectArrayTypeInfo<?, ?>) inTypeInfo).getComponentInfo();
        }
        info = createTypeInfoFromInput(returnTypeVar, inputTypeHierarchy, ((GenericArrayType) inType).getGenericComponentType(), componentInfo);
    } else // the input is a tuple
    if (inTypeInfo instanceof TupleTypeInfo && isClassType(inType) && Tuple.class.isAssignableFrom(typeToClass(inType))) {
        ParameterizedType tupleBaseClass;
        // get tuple from possible tuple subclass
        while (!(isClassType(inType) && typeToClass(inType).getSuperclass().equals(Tuple.class))) {
            inputTypeHierarchy.add(inType);
            inType = typeToClass(inType).getGenericSuperclass();
        }
        inputTypeHierarchy.add(inType);
        // we can assume to be parameterized since we
        // already did input validation
        tupleBaseClass = (ParameterizedType) inType;
        Type[] tupleElements = tupleBaseClass.getActualTypeArguments();
        // go thru all tuple elements and search for type variables
        for (int i = 0; i < tupleElements.length; i++) {
            info = createTypeInfoFromInput(returnTypeVar, inputTypeHierarchy, tupleElements[i], ((TupleTypeInfo<?>) inTypeInfo).getTypeAt(i));
            if (info != null) {
                break;
            }
        }
    } else // the input is a pojo
    if (inTypeInfo instanceof PojoTypeInfo && isClassType(inType)) {
        // build the entire type hierarchy for the pojo
        getTypeHierarchy(inputTypeHierarchy, inType, Object.class);
        // determine a field containing the type variable
        List<Field> fields = getAllDeclaredFields(typeToClass(inType), false);
        for (Field field : fields) {
            Type fieldType = field.getGenericType();
            if (fieldType instanceof TypeVariable && sameTypeVars(returnTypeVar, materializeTypeVariable(inputTypeHierarchy, (TypeVariable<?>) fieldType))) {
                return getTypeOfPojoField(inTypeInfo, field);
            } else if (fieldType instanceof ParameterizedType || fieldType instanceof GenericArrayType) {
                ArrayList<Type> typeHierarchyWithFieldType = new ArrayList<>(inputTypeHierarchy);
                typeHierarchyWithFieldType.add(fieldType);
                TypeInformation<?> foundInfo = createTypeInfoFromInput(returnTypeVar, typeHierarchyWithFieldType, fieldType, getTypeOfPojoField(inTypeInfo, field));
                if (foundInfo != null) {
                    return foundInfo;
                }
            }
        }
    }
    return info;
}
Also used : ArrayList(java.util.ArrayList) GenericArrayType(java.lang.reflect.GenericArrayType) TypeInformation(org.apache.flink.api.common.typeinfo.TypeInformation) ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) GenericArrayType(java.lang.reflect.GenericArrayType) TypeExtractionUtils.isClassType(org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType) Type(java.lang.reflect.Type) CompositeType(org.apache.flink.api.common.typeutils.CompositeType) ParameterizedType(java.lang.reflect.ParameterizedType) TypeVariable(java.lang.reflect.TypeVariable) PrimitiveArrayTypeInfo(org.apache.flink.api.common.typeinfo.PrimitiveArrayTypeInfo) List(java.util.List) ArrayList(java.util.ArrayList) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) BasicArrayTypeInfo(org.apache.flink.api.common.typeinfo.BasicArrayTypeInfo) Tuple(org.apache.flink.api.java.tuple.Tuple)

Example 20 with InvalidTypesException

use of org.apache.flink.api.common.functions.InvalidTypesException in project flink by apache.

the class UdfOperatorUtils method analyzeSingleInputUdf.

public static void analyzeSingleInputUdf(SingleInputUdfOperator<?, ?, ?> operator, Class<?> udfBaseClass, String defaultName, Function udf, Keys<?> key) {
    final CodeAnalysisMode mode = operator.getExecutionEnvironment().getConfig().getCodeAnalysisMode();
    if (mode != CodeAnalysisMode.DISABLE && !udf.getClass().isAnnotationPresent(FunctionAnnotation.SkipCodeAnalysis.class)) {
        final String operatorName = operator.getName() != null ? operator.getName() : udfBaseClass.getSimpleName() + " at " + defaultName;
        try {
            final UdfAnalyzer analyzer = new UdfAnalyzer(udfBaseClass, udf.getClass(), operatorName, operator.getInputType(), null, operator.getResultType(), key, null, mode == CodeAnalysisMode.OPTIMIZE);
            final boolean success = analyzer.analyze();
            if (success) {
                if (mode == CodeAnalysisMode.OPTIMIZE && !operator.udfWithForwardedFieldsAnnotation(udf.getClass())) {
                    analyzer.addSemanticPropertiesHints();
                    operator.setSemanticProperties((SingleInputSemanticProperties) analyzer.getSemanticProperties());
                    operator.setAnalyzedUdfSemanticsFlag();
                } else if (mode == CodeAnalysisMode.HINT) {
                    analyzer.addSemanticPropertiesHints();
                }
                analyzer.printToLogger(LOG);
            }
        } catch (InvalidTypesException e) {
            LOG.debug("Unable to do code analysis due to missing type information.", e);
        } catch (CodeAnalyzerException e) {
            LOG.debug("Code analysis failed.", e);
        }
    }
}
Also used : UdfAnalyzer(org.apache.flink.api.java.sca.UdfAnalyzer) CodeAnalyzerException(org.apache.flink.api.java.sca.CodeAnalyzerException) CodeAnalysisMode(org.apache.flink.api.common.CodeAnalysisMode) InvalidTypesException(org.apache.flink.api.common.functions.InvalidTypesException) FunctionAnnotation(org.apache.flink.api.java.functions.FunctionAnnotation)

Aggregations

InvalidTypesException (org.apache.flink.api.common.functions.InvalidTypesException)31 GenericArrayType (java.lang.reflect.GenericArrayType)19 ParameterizedType (java.lang.reflect.ParameterizedType)19 Type (java.lang.reflect.Type)19 CompositeType (org.apache.flink.api.common.typeutils.CompositeType)19 TypeExtractionUtils.isClassType (org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType)19 ArrayList (java.util.ArrayList)12 TypeInformation (org.apache.flink.api.common.typeinfo.TypeInformation)12 Field (java.lang.reflect.Field)6 TypeVariable (java.lang.reflect.TypeVariable)6 PrimitiveArrayTypeInfo (org.apache.flink.api.common.typeinfo.PrimitiveArrayTypeInfo)6 Method (java.lang.reflect.Method)5 PublicEvolving (org.apache.flink.annotation.PublicEvolving)5 BasicArrayTypeInfo (org.apache.flink.api.common.typeinfo.BasicArrayTypeInfo)5 Tuple (org.apache.flink.api.java.tuple.Tuple)5 TypeExtractionUtils.typeToClass (org.apache.flink.api.java.typeutils.TypeExtractionUtils.typeToClass)5 BasicTypeInfo (org.apache.flink.api.common.typeinfo.BasicTypeInfo)4 LambdaExecutable (org.apache.flink.api.java.typeutils.TypeExtractionUtils.LambdaExecutable)4 SqlTimeTypeInfo (org.apache.flink.api.common.typeinfo.SqlTimeTypeInfo)3 Constructor (java.lang.reflect.Constructor)2