use of org.apache.flink.table.runtime.generated.GeneratedRecordComparator in project flink by apache.
the class StreamExecTemporalSort method createSortProcTime.
/**
* Create Sort logic based on processing time.
*/
private Transformation<RowData> createSortProcTime(RowType inputType, Transformation<RowData> inputTransform, ExecNodeConfig config) {
// if the order has secondary sorting fields in addition to the proctime
if (sortSpec.getFieldSize() > 1) {
// skip the first field which is the proctime field and would be ordered by timer.
SortSpec specExcludeTime = sortSpec.createSubSortSpec(1);
GeneratedRecordComparator rowComparator = ComparatorCodeGenerator.gen(config.getTableConfig(), "ProcTimeSortComparator", inputType, specExcludeTime);
ProcTimeSortOperator sortOperator = new ProcTimeSortOperator(InternalTypeInfo.of(inputType), rowComparator);
OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(TEMPORAL_SORT_TRANSFORMATION, config), sortOperator, InternalTypeInfo.of(inputType), inputTransform.getParallelism());
// as input node is singleton exchange, its parallelism is 1.
if (inputsContainSingleton()) {
transform.setParallelism(1);
transform.setMaxParallelism(1);
}
EmptyRowDataKeySelector selector = EmptyRowDataKeySelector.INSTANCE;
transform.setStateKeySelector(selector);
transform.setStateKeyType(selector.getProducedType());
return transform;
} else {
// if the order is done only on proctime we only need to forward the elements
return inputTransform;
}
}
use of org.apache.flink.table.runtime.generated.GeneratedRecordComparator in project flink by apache.
the class StreamExecTemporalSort method createSortRowTime.
/**
* Create Sort logic based on row time.
*/
private Transformation<RowData> createSortRowTime(RowType inputType, Transformation<RowData> inputTransform, ExecNodeConfig config) {
GeneratedRecordComparator rowComparator = null;
if (sortSpec.getFieldSize() > 1) {
// skip the first field which is the rowtime field and would be ordered by timer.
SortSpec specExcludeTime = sortSpec.createSubSortSpec(1);
rowComparator = ComparatorCodeGenerator.gen(config.getTableConfig(), "RowTimeSortComparator", inputType, specExcludeTime);
}
RowTimeSortOperator sortOperator = new RowTimeSortOperator(InternalTypeInfo.of(inputType), sortSpec.getFieldSpec(0).getFieldIndex(), rowComparator);
OneInputTransformation<RowData, RowData> transform = ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(TEMPORAL_SORT_TRANSFORMATION, config), sortOperator, InternalTypeInfo.of(inputType), inputTransform.getParallelism());
if (inputsContainSingleton()) {
transform.setParallelism(1);
transform.setMaxParallelism(1);
}
EmptyRowDataKeySelector selector = EmptyRowDataKeySelector.INSTANCE;
transform.setStateKeySelector(selector);
transform.setStateKeyType(selector.getProducedType());
return transform;
}
use of org.apache.flink.table.runtime.generated.GeneratedRecordComparator in project flink by apache.
the class StreamExecSort method translateToPlanInternal.
@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
if (!config.get(InternalConfigOptions.TABLE_EXEC_NON_TEMPORAL_SORT_ENABLED)) {
throw new TableException("Sort on a non-time-attribute field is not supported.");
}
ExecEdge inputEdge = getInputEdges().get(0);
RowType inputType = (RowType) inputEdge.getOutputType();
// sort code gen
GeneratedRecordComparator rowComparator = ComparatorCodeGenerator.gen(config.getTableConfig(), "StreamExecSortComparator", inputType, sortSpec);
StreamSortOperator sortOperator = new StreamSortOperator(InternalTypeInfo.of(inputType), rowComparator);
Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
return ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationMeta(SORT_TRANSFORMATION, config), sortOperator, InternalTypeInfo.of(inputType), inputTransform.getParallelism());
}
use of org.apache.flink.table.runtime.generated.GeneratedRecordComparator 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.runtime.generated.GeneratedRecordComparator in project flink by apache.
the class BatchExecSortLimit method translateToPlanInternal.
@SuppressWarnings("unchecked")
@Override
protected Transformation<RowData> translateToPlanInternal(PlannerBase planner, ExecNodeConfig config) {
if (limitEnd == Long.MAX_VALUE) {
throw new TableException("Not support limitEnd is max value now!");
}
ExecEdge inputEdge = getInputEdges().get(0);
Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
RowType inputType = (RowType) inputEdge.getOutputType();
// generate comparator
GeneratedRecordComparator genComparator = ComparatorCodeGenerator.gen(config.getTableConfig(), "SortLimitComparator", inputType, sortSpec);
// TODO If input is ordered, there is no need to use the heap.
SortLimitOperator operator = new SortLimitOperator(isGlobal, limitStart, limitEnd, genComparator);
return ExecNodeUtil.createOneInputTransformation(inputTransform, createTransformationName(config), createTransformationDescription(config), SimpleOperatorFactory.of(operator), InternalTypeInfo.of(inputType), inputTransform.getParallelism());
}
Aggregations