use of org.apache.flink.table.planner.plan.utils.AggregateInfoList in project flink by apache.
the class StreamExecGlobalWindowAggregate 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);
final AggregateInfoList localAggInfoList = AggregateUtil.deriveStreamWindowAggregateInfoList(// should use original input here
localAggInputRowType, JavaScalaConversionUtil.toScala(Arrays.asList(aggCalls)), windowing.getWindow(), // isStateBackendDataViews
false);
final AggregateInfoList globalAggInfoList = AggregateUtil.deriveStreamWindowAggregateInfoList(// should use original input here
localAggInputRowType, JavaScalaConversionUtil.toScala(Arrays.asList(aggCalls)), windowing.getWindow(), // isStateBackendDataViews
true);
// handler used to merge multiple local accumulators into one accumulator,
// where the accumulators are all on memory
final GeneratedNamespaceAggsHandleFunction<Long> localAggsHandler = createAggsHandler("LocalWindowAggsHandler", sliceAssigner, localAggInfoList, grouping.length, true, localAggInfoList.getAccTypes(), config, planner.getRelBuilder(), shiftTimeZone);
// handler used to merge the single local accumulator (on memory) into state accumulator
final GeneratedNamespaceAggsHandleFunction<Long> globalAggsHandler = createAggsHandler("GlobalWindowAggsHandler", sliceAssigner, globalAggInfoList, 0, true, localAggInfoList.getAccTypes(), config, planner.getRelBuilder(), shiftTimeZone);
// handler used to merge state accumulators for merging slices into window,
// e.g. Hop and Cumulate
final GeneratedNamespaceAggsHandleFunction<Long> stateAggsHandler = createAggsHandler("StateWindowAggsHandler", sliceAssigner, globalAggInfoList, 0, false, globalAggInfoList.getAccTypes(), config, planner.getRelBuilder(), shiftTimeZone);
final RowDataKeySelector selector = KeySelectorUtil.getRowDataSelector(grouping, InternalTypeInfo.of(inputRowType));
final LogicalType[] accTypes = convertToLogicalTypes(globalAggInfoList.getAccTypes());
final OneInputStreamOperator<RowData, RowData> windowOperator = SlicingWindowAggOperatorBuilder.builder().inputSerializer(new RowDataSerializer(inputRowType)).shiftTimeZone(shiftTimeZone).keySerializer((PagedTypeSerializer<RowData>) selector.getProducedType().toSerializer()).assigner(sliceAssigner).countStarIndex(globalAggInfoList.getIndexOfCountStar()).globalAggregate(localAggsHandler, globalAggsHandler, stateAggsHandler, new RowDataSerializer(accTypes)).build();
final OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(GLOBAL_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;
}
use of org.apache.flink.table.planner.plan.utils.AggregateInfoList in project flink by apache.
the class StreamExecGroupTableAggregate method translateToPlanInternal.
@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
if (grouping.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 AggsHandlerCodeGenerator generator = new AggsHandlerCodeGenerator(new CodeGeneratorContext(config.getTableConfig()), planner.getRelBuilder(), JavaScalaConversionUtil.toScala(inputRowType.getChildren()), // TODO: but other operators do not copy this input field.....
true).needAccumulate();
if (needRetraction) {
generator.needRetract();
}
final AggregateInfoList aggInfoList = AggregateUtil.transformToStreamAggregateInfoList(inputRowType, JavaScalaConversionUtil.toScala(Arrays.asList(aggCalls)), aggCallNeedRetractions, needRetraction, // isStateBackendDataViews
true, // needDistinctInfo
true);
final GeneratedTableAggsHandleFunction aggsHandler = generator.generateTableAggsHandler("GroupTableAggHandler", aggInfoList);
final LogicalType[] accTypes = Arrays.stream(aggInfoList.getAccTypes()).map(LogicalTypeDataTypeConverter::fromDataTypeToLogicalType).toArray(LogicalType[]::new);
final int inputCountIndex = aggInfoList.getIndexOfCountStar();
final GroupTableAggFunction aggFunction = new GroupTableAggFunction(aggsHandler, accTypes, inputCountIndex, generateUpdateBefore, config.getStateRetentionTime());
final OneInputStreamOperator<RowData, RowData> operator = new KeyedProcessOperator<>(aggFunction);
// partitioned aggregation
final OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(GROUP_TABLE_AGGREGATE_TRANSFORMATION, config), operator, InternalTypeInfo.of(getOutputType()), inputTransform.getParallelism());
// set KeyType and Selector for state
final RowDataKeySelector selector = KeySelectorUtil.getRowDataSelector(grouping, InternalTypeInfo.of(inputRowType));
transform.setStateKeySelector(selector);
transform.setStateKeyType(selector.getProducedType());
return transform;
}
use of org.apache.flink.table.planner.plan.utils.AggregateInfoList in project flink by apache.
the class BatchExecHashWindowAggregate 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 aggInfos = AggregateUtil.transformToBatchAggregateInfoList(aggInputRowType, JavaScalaConversionUtil.toScala(Arrays.asList(aggCalls)), // aggCallNeedRetractions
null, // orderKeyIndexes
null);
final RowType inputRowType = (RowType) inputEdge.getOutputType();
final HashWindowCodeGenerator hashWindowCodeGenerator = new HashWindowCodeGenerator(new CodeGeneratorContext(config.getTableConfig()), planner.getRelBuilder(), window, inputTimeFieldIndex, inputTimeIsDate, JavaScalaConversionUtil.toScala(Arrays.asList(namedWindowProperties)), aggInfos, inputRowType, grouping, auxGrouping, enableAssignPane, isMerge, isFinal);
final int groupBufferLimitSize = config.get(ExecutionConfigOptions.TABLE_EXEC_WINDOW_AGG_BUFFER_SIZE_LIMIT);
final Tuple2<Long, Long> windowSizeAndSlideSize = WindowCodeGenerator.getWindowDef(window);
final GeneratedOperator<OneInputStreamOperator<RowData, RowData>> generatedOperator = hashWindowCodeGenerator.gen(inputRowType, (RowType) getOutputType(), groupBufferLimitSize, // windowStart
0, windowSizeAndSlideSize.f0, windowSizeAndSlideSize.f1);
final long managedMemory = config.get(ExecutionConfigOptions.TABLE_EXEC_RESOURCE_HASH_AGG_MEMORY).getBytes();
return ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationName(config), createTransformationDescription(config), new CodeGenOperatorFactory<>(generatedOperator), InternalTypeInfo.of(getOutputType()), inputTransform.getParallelism(), managedMemory);
}
use of org.apache.flink.table.planner.plan.utils.AggregateInfoList in project flink by apache.
the class BatchExecOverAggregate method createOverWindowFrames.
private List<OverWindowFrame> createOverWindowFrames(FlinkRelBuilder relBuilder, ExecNodeConfig config, RowType inputType, SortSpec sortSpec, RowType inputTypeWithConstants) {
final List<OverWindowFrame> windowFrames = new ArrayList<>();
for (GroupSpec group : overSpec.getGroups()) {
OverWindowMode mode = inferGroupMode(group);
if (mode == OverWindowMode.OFFSET) {
for (AggregateCall aggCall : group.getAggCalls()) {
AggregateInfoList aggInfoList = AggregateUtil.transformToBatchAggregateInfoList(inputTypeWithConstants, JavaScalaConversionUtil.toScala(Collections.singletonList(aggCall)), new boolean[] { true }, /* needRetraction = true, See LeadLagAggFunction */
sortSpec.getFieldIndices());
AggsHandlerCodeGenerator generator = new AggsHandlerCodeGenerator(new CodeGeneratorContext(config.getTableConfig()), relBuilder, JavaScalaConversionUtil.toScala(inputType.getChildren()), // copyInputField
false);
// over agg code gen must pass the constants
GeneratedAggsHandleFunction genAggsHandler = generator.needAccumulate().needRetract().withConstants(JavaScalaConversionUtil.toScala(getConstants())).generateAggsHandler("BoundedOverAggregateHelper", aggInfoList);
// LEAD is behind the currentRow, so we need plus offset.
// LAG is in front of the currentRow, so we need minus offset.
long flag = aggCall.getAggregation().kind == SqlKind.LEAD ? 1L : -1L;
final Long offset;
final OffsetOverFrame.CalcOffsetFunc calcOffsetFunc;
// The second arg mean the offset arg index for leag/lag function, default is 1.
if (aggCall.getArgList().size() >= 2) {
int constantIndex = aggCall.getArgList().get(1) - overSpec.getOriginalInputFields();
if (constantIndex < 0) {
offset = null;
int rowIndex = aggCall.getArgList().get(1);
switch(inputType.getTypeAt(rowIndex).getTypeRoot()) {
case BIGINT:
calcOffsetFunc = row -> row.getLong(rowIndex) * flag;
break;
case INTEGER:
calcOffsetFunc = row -> (long) row.getInt(rowIndex) * flag;
break;
case SMALLINT:
calcOffsetFunc = row -> (long) row.getShort(rowIndex) * flag;
break;
default:
throw new RuntimeException("The column type must be in long/int/short.");
}
} else {
long constantOffset = getConstants().get(constantIndex).getValueAs(Long.class);
offset = constantOffset * flag;
calcOffsetFunc = null;
}
} else {
offset = flag;
calcOffsetFunc = null;
}
windowFrames.add(new OffsetOverFrame(genAggsHandler, offset, calcOffsetFunc));
}
} else {
AggregateInfoList aggInfoList = AggregateUtil.transformToBatchAggregateInfoList(// inputSchema.relDataType
inputTypeWithConstants, JavaScalaConversionUtil.toScala(group.getAggCalls()), // aggCallNeedRetractions
null, sortSpec.getFieldIndices());
AggsHandlerCodeGenerator generator = new AggsHandlerCodeGenerator(new CodeGeneratorContext(config.getTableConfig()), relBuilder, JavaScalaConversionUtil.toScala(inputType.getChildren()), // copyInputField
false);
// over agg code gen must pass the constants
GeneratedAggsHandleFunction genAggsHandler = generator.needAccumulate().withConstants(JavaScalaConversionUtil.toScala(getConstants())).generateAggsHandler("BoundedOverAggregateHelper", aggInfoList);
RowType valueType = generator.valueType();
final OverWindowFrame frame;
switch(mode) {
case RANGE:
if (isUnboundedWindow(group)) {
frame = new UnboundedOverWindowFrame(genAggsHandler, valueType);
} else if (isUnboundedPrecedingWindow(group)) {
GeneratedRecordComparator genBoundComparator = createBoundComparator(relBuilder, config, sortSpec, group.getUpperBound(), false, inputType);
frame = new RangeUnboundedPrecedingOverFrame(genAggsHandler, genBoundComparator);
} else if (isUnboundedFollowingWindow(group)) {
GeneratedRecordComparator genBoundComparator = createBoundComparator(relBuilder, config, sortSpec, group.getLowerBound(), true, inputType);
frame = new RangeUnboundedFollowingOverFrame(valueType, genAggsHandler, genBoundComparator);
} else if (isSlidingWindow(group)) {
GeneratedRecordComparator genLeftBoundComparator = createBoundComparator(relBuilder, config, sortSpec, group.getLowerBound(), true, inputType);
GeneratedRecordComparator genRightBoundComparator = createBoundComparator(relBuilder, config, sortSpec, group.getUpperBound(), false, inputType);
frame = new RangeSlidingOverFrame(inputType, valueType, genAggsHandler, genLeftBoundComparator, genRightBoundComparator);
} else {
throw new TableException("This should not happen.");
}
break;
case ROW:
if (isUnboundedWindow(group)) {
frame = new UnboundedOverWindowFrame(genAggsHandler, valueType);
} else if (isUnboundedPrecedingWindow(group)) {
frame = new RowUnboundedPrecedingOverFrame(genAggsHandler, OverAggregateUtil.getLongBoundary(overSpec, group.getUpperBound()));
} else if (isUnboundedFollowingWindow(group)) {
frame = new RowUnboundedFollowingOverFrame(valueType, genAggsHandler, OverAggregateUtil.getLongBoundary(overSpec, group.getLowerBound()));
} else if (isSlidingWindow(group)) {
frame = new RowSlidingOverFrame(inputType, valueType, genAggsHandler, OverAggregateUtil.getLongBoundary(overSpec, group.getLowerBound()), OverAggregateUtil.getLongBoundary(overSpec, group.getUpperBound()));
} else {
throw new TableException("This should not happen.");
}
break;
case INSENSITIVE:
frame = new InsensitiveOverFrame(genAggsHandler);
break;
default:
throw new TableException("This should not happen.");
}
windowFrames.add(frame);
}
}
return windowFrames;
}
use of org.apache.flink.table.planner.plan.utils.AggregateInfoList in project flink by apache.
the class BatchExecHashAggregate 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 RowType outputRowType = (RowType) getOutputType();
final CodeGeneratorContext ctx = new CodeGeneratorContext(config.getTableConfig());
final AggregateInfoList aggInfos = AggregateUtil.transformToBatchAggregateInfoList(aggInputRowType, JavaScalaConversionUtil.toScala(Arrays.asList(aggCalls)), // aggCallNeedRetractions
null, // orderKeyIndexes
null);
final long managedMemory;
final GeneratedOperator<OneInputStreamOperator<RowData, RowData>> generatedOperator;
if (grouping.length == 0) {
managedMemory = 0L;
generatedOperator = AggWithoutKeysCodeGenerator.genWithoutKeys(ctx, planner.getRelBuilder(), aggInfos, inputRowType, outputRowType, isMerge, isFinal, "NoGrouping");
} else {
managedMemory = config.get(ExecutionConfigOptions.TABLE_EXEC_RESOURCE_HASH_AGG_MEMORY).getBytes();
generatedOperator = new HashAggCodeGenerator(ctx, planner.getRelBuilder(), aggInfos, inputRowType, outputRowType, grouping, auxGrouping, isMerge, isFinal).genWithKeys();
}
return ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationName(config), createTransformationDescription(config), new CodeGenOperatorFactory<>(generatedOperator), InternalTypeInfo.of(outputRowType), inputTransform.getParallelism(), managedMemory);
}
Aggregations