Search in sources :

Example 1 with CastExecutor

use of org.apache.flink.table.data.utils.CastExecutor in project flink by apache.

the class AbstractCodeGeneratorCastRule method create.

@SuppressWarnings("unchecked")
@Override
public CastExecutor<IN, OUT> create(CastRule.Context castRuleContext, LogicalType inputLogicalType, LogicalType targetLogicalType) {
    final String inputTerm = "_myInput";
    final String inputIsNullTerm = "_myInputIsNull";
    final String castExecutorClassName = CodeGenUtils.newName("GeneratedCastExecutor");
    final String inputTypeTerm = CodeGenUtils.boxedTypeTermForType(inputLogicalType);
    final CastExecutorCodeGeneratorContext ctx = new CastExecutorCodeGeneratorContext(castRuleContext);
    final CastCodeBlock codeBlock = generateCodeBlock(ctx, inputTerm, inputIsNullTerm, inputLogicalType, targetLogicalType);
    // Class fields can contain type serializers
    final String classFieldDecls = Stream.concat(ctx.typeSerializers.values().stream().map(entry -> "private final " + className(entry.getValue().getClass()) + " " + entry.getKey() + ";"), ctx.getClassFields().stream()).collect(Collectors.joining("\n"));
    final String constructorSignature = "public " + castExecutorClassName + "(" + ctx.typeSerializers.values().stream().map(entry -> className(entry.getValue().getClass()) + " " + entry.getKey()).collect(Collectors.joining(", ")) + ")";
    final String constructorBody = ctx.getDeclaredTypeSerializers().stream().map(name -> "this." + name + " = " + name + ";\n").collect(Collectors.joining());
    // Because janino doesn't support generics, we need to manually cast the input variable of
    // the cast method
    final String functionSignature = "@Override public Object cast(Object _myInputObj) throws " + className(TableException.class);
    // Write the function body
    final CastRuleUtils.CodeWriter bodyWriter = new CastRuleUtils.CodeWriter();
    bodyWriter.declStmt(inputTypeTerm, inputTerm, cast(inputTypeTerm, "_myInputObj"));
    bodyWriter.declStmt("boolean", inputIsNullTerm, "_myInputObj == null");
    ctx.variableDeclarationStatements.forEach(decl -> bodyWriter.appendBlock(decl + "\n"));
    if (this.canFail(inputLogicalType, targetLogicalType)) {
        bodyWriter.tryCatchStmt(tryWriter -> tryWriter.append(codeBlock).stmt("return " + codeBlock.getReturnTerm()), (exceptionTerm, catchWriter) -> catchWriter.throwStmt(constructorCall(TableException.class, strLiteral("Error when casting " + inputLogicalType + " to " + targetLogicalType + "."), exceptionTerm)));
    } else {
        bodyWriter.append(codeBlock).stmt("return " + codeBlock.getReturnTerm());
    }
    final String classCode = "public final class " + castExecutorClassName + " implements " + className(CastExecutor.class) + " {\n" + classFieldDecls + "\n" + constructorSignature + " {\n" + constructorBody + "}\n" + functionSignature + " {\n" + bodyWriter + "}\n}";
    try {
        Object[] constructorArgs = ctx.getTypeSerializersInstances().toArray(new TypeSerializer[0]);
        return (CastExecutor<IN, OUT>) CompileUtils.compile(castRuleContext.getClassLoader(), castExecutorClassName, classCode).getConstructors()[0].newInstance(constructorArgs);
    } catch (Throwable e) {
        throw new FlinkRuntimeException("Cast executor cannot be instantiated. This is a bug. Please file an issue. Code:\n" + classCode, e);
    }
}
Also used : TypeSerializer(org.apache.flink.api.common.typeutils.TypeSerializer) CastRuleUtils.strLiteral(org.apache.flink.table.planner.functions.casting.CastRuleUtils.strLiteral) CompileUtils(org.apache.flink.table.runtime.generated.CompileUtils) FlinkRuntimeException(org.apache.flink.util.FlinkRuntimeException) TableException(org.apache.flink.table.api.TableException) CodeGenUtils.className(org.apache.flink.table.planner.codegen.CodeGenUtils.className) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) CastRuleUtils.cast(org.apache.flink.table.planner.functions.casting.CastRuleUtils.cast) CastExecutor(org.apache.flink.table.data.utils.CastExecutor) List(java.util.List) CodeGenUtils(org.apache.flink.table.planner.codegen.CodeGenUtils) Stream(java.util.stream.Stream) LogicalType(org.apache.flink.table.types.logical.LogicalType) CastRuleUtils.constructorCall(org.apache.flink.table.planner.functions.casting.CastRuleUtils.constructorCall) InternalSerializers(org.apache.flink.table.runtime.typeutils.InternalSerializers) Map(java.util.Map) TableException(org.apache.flink.table.api.TableException) CastExecutor(org.apache.flink.table.data.utils.CastExecutor) FlinkRuntimeException(org.apache.flink.util.FlinkRuntimeException)

Aggregations

SimpleImmutableEntry (java.util.AbstractMap.SimpleImmutableEntry)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 TypeSerializer (org.apache.flink.api.common.typeutils.TypeSerializer)1 TableException (org.apache.flink.table.api.TableException)1 CastExecutor (org.apache.flink.table.data.utils.CastExecutor)1 CodeGenUtils (org.apache.flink.table.planner.codegen.CodeGenUtils)1 CodeGenUtils.className (org.apache.flink.table.planner.codegen.CodeGenUtils.className)1 CastRuleUtils.cast (org.apache.flink.table.planner.functions.casting.CastRuleUtils.cast)1 CastRuleUtils.constructorCall (org.apache.flink.table.planner.functions.casting.CastRuleUtils.constructorCall)1 CastRuleUtils.strLiteral (org.apache.flink.table.planner.functions.casting.CastRuleUtils.strLiteral)1 CompileUtils (org.apache.flink.table.runtime.generated.CompileUtils)1 InternalSerializers (org.apache.flink.table.runtime.typeutils.InternalSerializers)1 LogicalType (org.apache.flink.table.types.logical.LogicalType)1 FlinkRuntimeException (org.apache.flink.util.FlinkRuntimeException)1