Search in sources :

Example 21 with OneInputTransformation

use of org.apache.flink.streaming.api.transformations.OneInputTransformation in project flink by apache.

the class StreamExecMatch method translateToPlanInternal.

@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
    final ExecEdge inputEdge = getInputEdges().get(0);
    final Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
    final RowType inputRowType = (RowType) inputEdge.getOutputType();
    checkOrderKeys(inputRowType);
    final EventComparator<RowData> eventComparator = createEventComparator(config, inputRowType);
    final Transformation<RowData> timestampedInputTransform = translateOrder(inputTransform, inputRowType);
    final Tuple2<Pattern<RowData, RowData>, List<String>> cepPatternAndNames = translatePattern(matchSpec, config.getTableConfig(), planner.getRelBuilder(), inputRowType);
    final Pattern<RowData, RowData> cepPattern = cepPatternAndNames.f0;
    // TODO remove this once it is supported in CEP library
    if (NFACompiler.canProduceEmptyMatches(cepPattern)) {
        throw new TableException("Patterns that can produce empty matches are not supported. There must be at least one non-optional state.");
    }
    // TODO remove this once it is supported in CEP library
    if (cepPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) {
        throw new TableException("Greedy quantifiers are not allowed as the last element of a Pattern yet. " + "Finish your pattern with either a simple variable or reluctant quantifier.");
    }
    if (matchSpec.isAllRows()) {
        throw new TableException("All rows per match mode is not supported yet.");
    }
    final int[] partitionKeys = matchSpec.getPartition().getFieldIndices();
    final SortSpec.SortFieldSpec timeOrderField = matchSpec.getOrderKeys().getFieldSpec(0);
    final LogicalType timeOrderFieldType = inputRowType.getTypeAt(timeOrderField.getFieldIndex());
    final boolean isProctime = TypeCheckUtils.isProcTime(timeOrderFieldType);
    final InternalTypeInfo<RowData> inputTypeInfo = (InternalTypeInfo<RowData>) inputTransform.getOutputType();
    final TypeSerializer<RowData> inputSerializer = inputTypeInfo.createSerializer(planner.getExecEnv().getConfig());
    final NFACompiler.NFAFactory<RowData> nfaFactory = NFACompiler.compileFactory(cepPattern, false);
    final MatchCodeGenerator generator = new MatchCodeGenerator(new CodeGeneratorContext(config.getTableConfig()), planner.getRelBuilder(), // nullableInput
    false, JavaScalaConversionUtil.toScala(cepPatternAndNames.f1), JavaScalaConversionUtil.toScala(Optional.empty()), CodeGenUtils.DEFAULT_COLLECTOR_TERM());
    generator.bindInput(inputRowType, CodeGenUtils.DEFAULT_INPUT1_TERM(), JavaScalaConversionUtil.toScala(Optional.empty()));
    final PatternProcessFunctionRunner patternProcessFunction = generator.generateOneRowPerMatchExpression((RowType) getOutputType(), partitionKeys, matchSpec.getMeasures());
    final CepOperator<RowData, RowData, RowData> operator = new CepOperator<>(inputSerializer, isProctime, nfaFactory, eventComparator, cepPattern.getAfterMatchSkipStrategy(), patternProcessFunction, null);
    final OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(timestampedInputTransform, createTransformationMeta(MATCH_TRANSFORMATION, config), operator, InternalTypeInfo.of(getOutputType()), timestampedInputTransform.getParallelism());
    final RowDataKeySelector selector = KeySelectorUtil.getRowDataSelector(partitionKeys, inputTypeInfo);
    transform.setStateKeySelector(selector);
    transform.setStateKeyType(selector.getProducedType());
    if (inputsContainSingleton()) {
        transform.setParallelism(1);
        transform.setMaxParallelism(1);
    }
    return transform;
}
Also used : OneInputTransformation(org.apache.flink.streaming.api.transformations.OneInputTransformation) Transformation(org.apache.flink.api.dag.Transformation) ExecEdge(org.apache.flink.table.planner.plan.nodes.exec.ExecEdge) RowType(org.apache.flink.table.types.logical.RowType) LogicalType(org.apache.flink.table.types.logical.LogicalType) NFACompiler(org.apache.flink.cep.nfa.compiler.NFACompiler) RowData(org.apache.flink.table.data.RowData) RowDataKeySelector(org.apache.flink.table.runtime.keyselector.RowDataKeySelector) List(java.util.List) ArrayList(java.util.ArrayList) Pattern(org.apache.flink.cep.pattern.Pattern) TableException(org.apache.flink.table.api.TableException) CodeGeneratorContext(org.apache.flink.table.planner.codegen.CodeGeneratorContext) InternalTypeInfo(org.apache.flink.table.runtime.typeutils.InternalTypeInfo) MatchCodeGenerator(org.apache.flink.table.planner.codegen.MatchCodeGenerator) PatternProcessFunctionRunner(org.apache.flink.table.runtime.operators.match.PatternProcessFunctionRunner) CepOperator(org.apache.flink.cep.operator.CepOperator) SortSpec(org.apache.flink.table.planner.plan.nodes.exec.spec.SortSpec)

Example 22 with OneInputTransformation

use of org.apache.flink.streaming.api.transformations.OneInputTransformation in project flink by apache.

the class StreamExecOverAggregate method translateToPlanInternal.

@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
    if (overSpec.getGroups().size() > 1) {
        throw new TableException("All aggregates must be computed on the same window.");
    }
    final OverSpec.GroupSpec group = overSpec.getGroups().get(0);
    final int[] orderKeys = group.getSort().getFieldIndices();
    final boolean[] isAscendingOrders = group.getSort().getAscendingOrders();
    if (orderKeys.length != 1 || isAscendingOrders.length != 1) {
        throw new TableException("The window can only be ordered by a single time column.");
    }
    if (!isAscendingOrders[0]) {
        throw new TableException("The window can only be ordered in ASCENDING mode.");
    }
    final int[] partitionKeys = overSpec.getPartition().getFieldIndices();
    if (partitionKeys.length > 0 && config.getStateRetentionTime() < 0) {
        LOG.warn("No state retention interval configured for a query which accumulates state. " + "Please provide a query configuration with valid retention interval to prevent " + "excessive state size. You may specify a retention time of 0 to not clean up the state.");
    }
    final ExecEdge inputEdge = getInputEdges().get(0);
    final Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
    final RowType inputRowType = (RowType) inputEdge.getOutputType();
    final int orderKey = orderKeys[0];
    final LogicalType orderKeyType = inputRowType.getFields().get(orderKey).getType();
    // check time field && identify window rowtime attribute
    final int rowTimeIdx;
    if (isRowtimeAttribute(orderKeyType)) {
        rowTimeIdx = orderKey;
    } else if (isProctimeAttribute(orderKeyType)) {
        rowTimeIdx = -1;
    } else {
        throw new TableException("OVER windows' ordering in stream mode must be defined on a time attribute.");
    }
    final List<RexLiteral> constants = overSpec.getConstants();
    final List<String> fieldNames = new ArrayList<>(inputRowType.getFieldNames());
    final List<LogicalType> fieldTypes = new ArrayList<>(inputRowType.getChildren());
    IntStream.range(0, constants.size()).forEach(i -> fieldNames.add("TMP" + i));
    for (int i = 0; i < constants.size(); ++i) {
        fieldNames.add("TMP" + i);
        fieldTypes.add(FlinkTypeFactory.toLogicalType(constants.get(i).getType()));
    }
    final RowType aggInputRowType = RowType.of(fieldTypes.toArray(new LogicalType[0]), fieldNames.toArray(new String[0]));
    final CodeGeneratorContext ctx = new CodeGeneratorContext(config.getTableConfig());
    final KeyedProcessFunction<RowData, RowData, RowData> overProcessFunction;
    if (group.getLowerBound().isPreceding() && group.getLowerBound().isUnbounded() && group.getUpperBound().isCurrentRow()) {
        // unbounded OVER window
        overProcessFunction = createUnboundedOverProcessFunction(ctx, group.getAggCalls(), constants, aggInputRowType, inputRowType, rowTimeIdx, group.isRows(), config, planner.getRelBuilder());
    } else if (group.getLowerBound().isPreceding() && !group.getLowerBound().isUnbounded() && group.getUpperBound().isCurrentRow()) {
        final Object boundValue = OverAggregateUtil.getBoundary(overSpec, group.getLowerBound());
        if (boundValue instanceof BigDecimal) {
            throw new TableException("the specific value is decimal which haven not supported yet.");
        }
        // bounded OVER window
        final long precedingOffset = -1 * (long) boundValue + (group.isRows() ? 1 : 0);
        overProcessFunction = createBoundedOverProcessFunction(ctx, group.getAggCalls(), constants, aggInputRowType, inputRowType, rowTimeIdx, group.isRows(), precedingOffset, config, planner.getRelBuilder());
    } else {
        throw new TableException("OVER RANGE FOLLOWING windows are not supported yet.");
    }
    final KeyedProcessOperator<RowData, RowData, RowData> operator = new KeyedProcessOperator<>(overProcessFunction);
    OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(OVER_AGGREGATE_TRANSFORMATION, config), operator, InternalTypeInfo.of(getOutputType()), inputTransform.getParallelism());
    // set KeyType and Selector for state
    final RowDataKeySelector selector = KeySelectorUtil.getRowDataSelector(partitionKeys, InternalTypeInfo.of(inputRowType));
    transform.setStateKeySelector(selector);
    transform.setStateKeyType(selector.getProducedType());
    return transform;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) OneInputTransformation(org.apache.flink.streaming.api.transformations.OneInputTransformation) Transformation(org.apache.flink.api.dag.Transformation) ExecEdge(org.apache.flink.table.planner.plan.nodes.exec.ExecEdge) ArrayList(java.util.ArrayList) RowType(org.apache.flink.table.types.logical.RowType) LogicalType(org.apache.flink.table.types.logical.LogicalType) RowData(org.apache.flink.table.data.RowData) RowDataKeySelector(org.apache.flink.table.runtime.keyselector.RowDataKeySelector) KeyedProcessOperator(org.apache.flink.streaming.api.operators.KeyedProcessOperator) TableException(org.apache.flink.table.api.TableException) CodeGeneratorContext(org.apache.flink.table.planner.codegen.CodeGeneratorContext) OverSpec(org.apache.flink.table.planner.plan.nodes.exec.spec.OverSpec) BigDecimal(java.math.BigDecimal)

Example 23 with OneInputTransformation

use of org.apache.flink.streaming.api.transformations.OneInputTransformation in project flink by apache.

the class StreamExecIncrementalGroupAggregate method translateToPlanInternal.

@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
    final ExecEdge inputEdge = getInputEdges().get(0);
    final Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
    final AggregateInfoList partialLocalAggInfoList = AggregateUtil.createPartialAggInfoList(partialLocalAggInputType, JavaScalaConversionUtil.toScala(Arrays.asList(partialOriginalAggCalls)), partialAggCallNeedRetractions, partialAggNeedRetraction, false);
    final GeneratedAggsHandleFunction partialAggsHandler = generateAggsHandler("PartialGroupAggsHandler", partialLocalAggInfoList, partialAggGrouping.length, partialLocalAggInfoList.getAccTypes(), config, planner.getRelBuilder(), // the partial aggregate accumulators will be buffered, so need copy
    true);
    final AggregateInfoList incrementalAggInfo = AggregateUtil.createIncrementalAggInfoList(partialLocalAggInputType, JavaScalaConversionUtil.toScala(Arrays.asList(partialOriginalAggCalls)), partialAggCallNeedRetractions, partialAggNeedRetraction);
    final GeneratedAggsHandleFunction finalAggsHandler = generateAggsHandler("FinalGroupAggsHandler", incrementalAggInfo, 0, partialLocalAggInfoList.getAccTypes(), config, planner.getRelBuilder(), // the final aggregate accumulators is not buffered
    false);
    final RowDataKeySelector partialKeySelector = KeySelectorUtil.getRowDataSelector(partialAggGrouping, InternalTypeInfo.of(inputEdge.getOutputType()));
    final RowDataKeySelector finalKeySelector = KeySelectorUtil.getRowDataSelector(finalAggGrouping, partialKeySelector.getProducedType());
    final MiniBatchIncrementalGroupAggFunction aggFunction = new MiniBatchIncrementalGroupAggFunction(partialAggsHandler, finalAggsHandler, finalKeySelector, config.getStateRetentionTime());
    final OneInputStreamOperator<RowData, RowData> operator = new KeyedMapBundleOperator<>(aggFunction, AggregateUtil.createMiniBatchTrigger(config));
    // partitioned aggregation
    final OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(INCREMENTAL_GROUP_AGGREGATE_TRANSFORMATION, config), operator, InternalTypeInfo.of(getOutputType()), inputTransform.getParallelism());
    // set KeyType and Selector for state
    transform.setStateKeySelector(partialKeySelector);
    transform.setStateKeyType(partialKeySelector.getProducedType());
    return transform;
}
Also used : RowData(org.apache.flink.table.data.RowData) OneInputTransformation(org.apache.flink.streaming.api.transformations.OneInputTransformation) Transformation(org.apache.flink.api.dag.Transformation) AggregateInfoList(org.apache.flink.table.planner.plan.utils.AggregateInfoList) ExecEdge(org.apache.flink.table.planner.plan.nodes.exec.ExecEdge) MiniBatchIncrementalGroupAggFunction(org.apache.flink.table.runtime.operators.aggregate.MiniBatchIncrementalGroupAggFunction) RowDataKeySelector(org.apache.flink.table.runtime.keyselector.RowDataKeySelector) GeneratedAggsHandleFunction(org.apache.flink.table.runtime.generated.GeneratedAggsHandleFunction) KeyedMapBundleOperator(org.apache.flink.table.runtime.operators.bundle.KeyedMapBundleOperator)

Example 24 with OneInputTransformation

use of org.apache.flink.streaming.api.transformations.OneInputTransformation in project flink by apache.

the class StreamExecPythonOverAggregate method translateToPlanInternal.

@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
    if (overSpec.getGroups().size() > 1) {
        throw new TableException("All aggregates must be computed on the same window.");
    }
    final OverSpec.GroupSpec group = overSpec.getGroups().get(0);
    final int[] orderKeys = group.getSort().getFieldIndices();
    final boolean[] isAscendingOrders = group.getSort().getAscendingOrders();
    if (orderKeys.length != 1 || isAscendingOrders.length != 1) {
        throw new TableException("The window can only be ordered by a single time column.");
    }
    if (!isAscendingOrders[0]) {
        throw new TableException("The window can only be ordered in ASCENDING mode.");
    }
    final int[] partitionKeys = overSpec.getPartition().getFieldIndices();
    if (partitionKeys.length > 0 && config.getStateRetentionTime() < 0) {
        LOG.warn("No state retention interval configured for a query which accumulates state. " + "Please provide a query configuration with valid retention interval to prevent " + "excessive state size. You may specify a retention time of 0 to not clean up the state.");
    }
    final ExecEdge inputEdge = getInputEdges().get(0);
    final Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
    final RowType inputRowType = (RowType) inputEdge.getOutputType();
    final int orderKey = orderKeys[0];
    final LogicalType orderKeyType = inputRowType.getFields().get(orderKey).getType();
    // check time field && identify window rowtime attribute
    final int rowTimeIdx;
    if (isRowtimeAttribute(orderKeyType)) {
        rowTimeIdx = orderKey;
    } else if (isProctimeAttribute(orderKeyType)) {
        rowTimeIdx = -1;
    } else {
        throw new TableException("OVER windows' ordering in stream mode must be defined on a time attribute.");
    }
    if (group.getLowerBound().isPreceding() && group.getLowerBound().isUnbounded()) {
        throw new TableException("Python UDAF is not supported to be used in UNBOUNDED PRECEDING OVER windows.");
    } else if (!group.getUpperBound().isCurrentRow()) {
        throw new TableException("Python UDAF is not supported to be used in UNBOUNDED FOLLOWING OVER windows.");
    }
    Object boundValue = OverAggregateUtil.getBoundary(overSpec, group.getLowerBound());
    if (boundValue instanceof BigDecimal) {
        throw new TableException("the specific value is decimal which haven not supported yet.");
    }
    long precedingOffset = -1 * (long) boundValue;
    Configuration pythonConfig = CommonPythonUtil.getMergedConfig(planner.getExecEnv(), config.getTableConfig());
    OneInputTransformation<RowData, RowData> transform = createPythonOneInputTransformation(inputTransform, inputRowType, InternalTypeInfo.of(getOutputType()).toRowType(), rowTimeIdx, group.getAggCalls().toArray(new AggregateCall[0]), precedingOffset, group.isRows(), config.getStateRetentionTime(), config.getMaxIdleStateRetentionTime(), pythonConfig, config);
    if (CommonPythonUtil.isPythonWorkerUsingManagedMemory(pythonConfig)) {
        transform.declareManagedMemoryUseCaseAtSlotScope(ManagedMemoryUseCase.PYTHON);
    }
    // set KeyType and Selector for state
    final RowDataKeySelector selector = KeySelectorUtil.getRowDataSelector(partitionKeys, InternalTypeInfo.of(inputRowType));
    transform.setStateKeySelector(selector);
    transform.setStateKeyType(selector.getProducedType());
    return transform;
}
Also used : TableException(org.apache.flink.table.api.TableException) OneInputTransformation(org.apache.flink.streaming.api.transformations.OneInputTransformation) Transformation(org.apache.flink.api.dag.Transformation) ExecEdge(org.apache.flink.table.planner.plan.nodes.exec.ExecEdge) Configuration(org.apache.flink.configuration.Configuration) RowType(org.apache.flink.table.types.logical.RowType) LogicalType(org.apache.flink.table.types.logical.LogicalType) OverSpec(org.apache.flink.table.planner.plan.nodes.exec.spec.OverSpec) BigDecimal(java.math.BigDecimal) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RowData(org.apache.flink.table.data.RowData) RowDataKeySelector(org.apache.flink.table.runtime.keyselector.RowDataKeySelector)

Example 25 with OneInputTransformation

use of org.apache.flink.streaming.api.transformations.OneInputTransformation in project flink by apache.

the class StreamExecWindowAggregate method translateToPlanInternal.

@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
    final ExecEdge inputEdge = getInputEdges().get(0);
    final Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
    final RowType inputRowType = (RowType) inputEdge.getOutputType();
    final ZoneId shiftTimeZone = TimeWindowUtil.getShiftTimeZone(windowing.getTimeAttributeType(), config.getLocalTimeZone());
    final SliceAssigner sliceAssigner = createSliceAssigner(windowing, shiftTimeZone);
    // Hopping window requires additional COUNT(*) to determine whether to register next timer
    // through whether the current fired window is empty, see SliceSharedWindowAggProcessor.
    final AggregateInfoList aggInfoList = AggregateUtil.deriveStreamWindowAggregateInfoList(inputRowType, JavaScalaConversionUtil.toScala(Arrays.asList(aggCalls)), windowing.getWindow(), // isStateBackendDataViews
    true);
    final GeneratedNamespaceAggsHandleFunction<Long> generatedAggsHandler = createAggsHandler(sliceAssigner, aggInfoList, config, planner.getRelBuilder(), inputRowType.getChildren(), shiftTimeZone);
    final RowDataKeySelector selector = KeySelectorUtil.getRowDataSelector(grouping, InternalTypeInfo.of(inputRowType));
    final LogicalType[] accTypes = convertToLogicalTypes(aggInfoList.getAccTypes());
    final OneInputStreamOperator<RowData, RowData> windowOperator = SlicingWindowAggOperatorBuilder.builder().inputSerializer(new RowDataSerializer(inputRowType)).shiftTimeZone(shiftTimeZone).keySerializer((PagedTypeSerializer<RowData>) selector.getProducedType().toSerializer()).assigner(sliceAssigner).countStarIndex(aggInfoList.getIndexOfCountStar()).aggregate(generatedAggsHandler, new RowDataSerializer(accTypes)).build();
    final OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(WINDOW_AGGREGATE_TRANSFORMATION, config), SimpleOperatorFactory.of(windowOperator), InternalTypeInfo.of(getOutputType()), inputTransform.getParallelism(), WINDOW_AGG_MEMORY_RATIO);
    // set KeyType and Selector for state
    transform.setStateKeySelector(selector);
    transform.setStateKeyType(selector.getProducedType());
    return transform;
}
Also used : SliceAssigner(org.apache.flink.table.runtime.operators.window.slicing.SliceAssigner) OneInputTransformation(org.apache.flink.streaming.api.transformations.OneInputTransformation) Transformation(org.apache.flink.api.dag.Transformation) AggregateInfoList(org.apache.flink.table.planner.plan.utils.AggregateInfoList) ExecEdge(org.apache.flink.table.planner.plan.nodes.exec.ExecEdge) ZoneId(java.time.ZoneId) RowType(org.apache.flink.table.types.logical.RowType) LogicalType(org.apache.flink.table.types.logical.LogicalType) RowData(org.apache.flink.table.data.RowData) RowDataKeySelector(org.apache.flink.table.runtime.keyselector.RowDataKeySelector) RowDataSerializer(org.apache.flink.table.runtime.typeutils.RowDataSerializer)

Aggregations

OneInputTransformation (org.apache.flink.streaming.api.transformations.OneInputTransformation)125 Test (org.junit.Test)95 StreamExecutionEnvironment (org.apache.flink.streaming.api.environment.StreamExecutionEnvironment)88 Tuple2 (org.apache.flink.api.java.tuple.Tuple2)76 TimeWindow (org.apache.flink.streaming.api.windowing.windows.TimeWindow)47 EventTimeTrigger (org.apache.flink.streaming.api.windowing.triggers.EventTimeTrigger)44 Tuple3 (org.apache.flink.api.java.tuple.Tuple3)43 ListStateDescriptor (org.apache.flink.api.common.state.ListStateDescriptor)34 Transformation (org.apache.flink.api.dag.Transformation)34 TumblingEventTimeWindows (org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows)30 RowData (org.apache.flink.table.data.RowData)26 SlidingEventTimeWindows (org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows)24 ExecEdge (org.apache.flink.table.planner.plan.nodes.exec.ExecEdge)24 ProcessingTimeTrigger (org.apache.flink.streaming.api.windowing.triggers.ProcessingTimeTrigger)21 RowType (org.apache.flink.table.types.logical.RowType)21 RowDataKeySelector (org.apache.flink.table.runtime.keyselector.RowDataKeySelector)19 FoldingStateDescriptor (org.apache.flink.api.common.state.FoldingStateDescriptor)17 ReducingStateDescriptor (org.apache.flink.api.common.state.ReducingStateDescriptor)17 TumblingProcessingTimeWindows (org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows)15 ExpectedException (org.junit.rules.ExpectedException)15