use of org.apache.flink.table.api.TableException 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.api.TableException in project flink by apache.
the class BatchExecPythonOverAggregate 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 inputType = (RowType) inputEdge.getOutputType();
List<OverSpec.GroupSpec> groups = overSpec.getGroups();
boolean[] isRangeWindows = new boolean[groups.size()];
for (int i = 0; i < groups.size(); i++) {
OverSpec.GroupSpec group = groups.get(i);
List<AggregateCall> groupAggCalls = group.getAggCalls();
aggCalls.addAll(groupAggCalls);
for (int j = 0; j < groupAggCalls.size(); j++) {
aggWindowIndex.add(i);
}
OverWindowMode mode = inferGroupMode(group);
if (mode == OverWindowMode.ROW) {
isRangeWindows[i] = false;
if (isUnboundedWindow(group)) {
lowerBoundary.add(Long.MIN_VALUE);
upperBoundary.add(Long.MAX_VALUE);
} else if (isUnboundedPrecedingWindow(group)) {
lowerBoundary.add(Long.MIN_VALUE);
upperBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getUpperBound()));
} else if (isUnboundedFollowingWindow(group)) {
lowerBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getLowerBound()));
upperBoundary.add(Long.MAX_VALUE);
} else if (isSlidingWindow(group)) {
lowerBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getLowerBound()));
upperBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getUpperBound()));
} else {
throw new TableException("Unsupported row window group spec " + group);
}
} else {
isRangeWindows[i] = true;
if (isUnboundedWindow(group)) {
lowerBoundary.add(Long.MIN_VALUE);
upperBoundary.add(Long.MAX_VALUE);
} else if (isUnboundedPrecedingWindow(group)) {
lowerBoundary.add(Long.MIN_VALUE);
upperBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getUpperBound()));
} else if (isUnboundedFollowingWindow(group)) {
lowerBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getLowerBound()));
upperBoundary.add(Long.MAX_VALUE);
} else if (isSlidingWindow(group)) {
lowerBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getLowerBound()));
upperBoundary.add(OverAggregateUtil.getLongBoundary(overSpec, group.getUpperBound()));
} else {
throw new TableException("Unsupported range window group spec " + group);
}
}
}
Configuration pythonConfig = CommonPythonUtil.getMergedConfig(planner.getExecEnv(), config.getTableConfig());
OneInputTransformation<RowData, RowData> transform = createPythonOneInputTransformation(inputTransform, inputType, InternalTypeInfo.of(getOutputType()).toRowType(), isRangeWindows, pythonConfig, config);
if (CommonPythonUtil.isPythonWorkerUsingManagedMemory(pythonConfig)) {
transform.declareManagedMemoryUseCaseAtSlotScope(ManagedMemoryUseCase.PYTHON);
}
return transform;
}
use of org.apache.flink.table.api.TableException in project flink by apache.
the class BatchExecPythonOverAggregate method getPythonOverWindowAggregateFunctionOperator.
@SuppressWarnings("unchecked")
private OneInputStreamOperator<RowData, RowData> getPythonOverWindowAggregateFunctionOperator(ExecNodeConfig config, Configuration pythonConfig, RowType inputRowType, RowType outputRowType, boolean[] isRangeWindows, int[] udafInputOffsets, PythonFunctionInfo[] pythonFunctionInfos) {
Class<?> clazz = CommonPythonUtil.loadClass(ARROW_PYTHON_OVER_WINDOW_AGGREGATE_FUNCTION_OPERATOR_NAME);
RowType udfInputType = (RowType) Projection.of(udafInputOffsets).project(inputRowType);
RowType udfOutputType = (RowType) Projection.range(inputRowType.getFieldCount(), outputRowType.getFieldCount()).project(outputRowType);
PartitionSpec partitionSpec = overSpec.getPartition();
List<OverSpec.GroupSpec> groups = overSpec.getGroups();
SortSpec sortSpec = groups.get(groups.size() - 1).getSort();
try {
Constructor<?> ctor = clazz.getConstructor(Configuration.class, PythonFunctionInfo[].class, RowType.class, RowType.class, RowType.class, long[].class, long[].class, boolean[].class, int[].class, int.class, boolean.class, GeneratedProjection.class, GeneratedProjection.class, GeneratedProjection.class);
return (OneInputStreamOperator<RowData, RowData>) ctor.newInstance(pythonConfig, pythonFunctionInfos, inputRowType, udfInputType, udfOutputType, lowerBoundary.stream().mapToLong(i -> i).toArray(), upperBoundary.stream().mapToLong(i -> i).toArray(), isRangeWindows, aggWindowIndex.stream().mapToInt(i -> i).toArray(), sortSpec.getFieldIndices()[0], sortSpec.getAscendingOrders()[0], ProjectionCodeGenerator.generateProjection(CodeGeneratorContext.apply(config.getTableConfig()), "UdafInputProjection", inputRowType, udfInputType, udafInputOffsets), ProjectionCodeGenerator.generateProjection(CodeGeneratorContext.apply(config.getTableConfig()), "GroupKey", inputRowType, (RowType) Projection.of(partitionSpec.getFieldIndices()).project(inputRowType), partitionSpec.getFieldIndices()), ProjectionCodeGenerator.generateProjection(CodeGeneratorContext.apply(config.getTableConfig()), "GroupSet", inputRowType, (RowType) Projection.of(partitionSpec.getFieldIndices()).project(inputRowType), partitionSpec.getFieldIndices()));
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new TableException("Python BatchArrowPythonOverWindowAggregateFunctionOperator constructed failed.", e);
}
}
use of org.apache.flink.table.api.TableException in project flink by apache.
the class CommonExecLegacySink method translateToTransformation.
/**
* Translates {@link TableSink} into a {@link Transformation}.
*
* @param withChangeFlag Set to true to emit records with change flags.
* @return The {@link Transformation} that corresponds to the translated {@link TableSink}.
*/
@SuppressWarnings("unchecked")
private Transformation<T> translateToTransformation(PlannerBase planner, ExecNodeConfig config, boolean withChangeFlag) {
// if no change flags are requested, verify table is an insert-only (append-only) table.
if (!withChangeFlag && needRetraction) {
throw new TableException("Table is not an append-only table. " + "Use the toRetractStream() in order to handle add and retract messages.");
}
final ExecEdge inputEdge = getInputEdges().get(0);
final Transformation<RowData> inputTransform = (Transformation<RowData>) inputEdge.translateToPlan(planner);
final RowType inputRowType = (RowType) inputEdge.getOutputType();
final RowType convertedInputRowType = checkAndConvertInputTypeIfNeeded(inputRowType);
final DataType resultDataType = tableSink.getConsumedDataType();
if (CodeGenUtils.isInternalClass(resultDataType)) {
return (Transformation<T>) inputTransform;
} else {
final int rowtimeIndex = getRowtimeIndex(inputRowType);
final DataType physicalOutputType = TableSinkUtils.inferSinkPhysicalDataType(resultDataType, convertedInputRowType, withChangeFlag);
final TypeInformation<T> outputTypeInfo = SinkCodeGenerator.deriveSinkOutputTypeInfo(tableSink, physicalOutputType, withChangeFlag);
final CodeGenOperatorFactory<T> converterOperator = SinkCodeGenerator.generateRowConverterOperator(new CodeGeneratorContext(config.getTableConfig()), convertedInputRowType, tableSink, physicalOutputType, withChangeFlag, "SinkConversion", rowtimeIndex);
final String description = "SinkConversion To " + resultDataType.getConversionClass().getSimpleName();
return ExecNodeUtil.createOneInputTransformation(inputTransform, createFormattedTransformationName(description, "SinkConversion", config), createFormattedTransformationDescription(description, config), converterOperator, outputTypeInfo, inputTransform.getParallelism());
}
}
use of org.apache.flink.table.api.TableException in project flink by apache.
the class CommonExecPythonCorrelate method getPythonTableFunctionOperator.
@SuppressWarnings("unchecked")
private OneInputStreamOperator<RowData, RowData> getPythonTableFunctionOperator(ExecNodeConfig config, Configuration pythonConfig, InternalTypeInfo<RowData> inputRowType, InternalTypeInfo<RowData> outputRowType, PythonFunctionInfo pythonFunctionInfo, int[] udtfInputOffsets) {
Class clazz = CommonPythonUtil.loadClass(PYTHON_TABLE_FUNCTION_OPERATOR_NAME);
final RowType inputType = inputRowType.toRowType();
final RowType outputType = outputRowType.toRowType();
final RowType udfInputType = (RowType) Projection.of(udtfInputOffsets).project(inputType);
final RowType udfOutputType = (RowType) Projection.range(inputType.getFieldCount(), outputType.getFieldCount()).project(outputType);
try {
Constructor ctor = clazz.getConstructor(Configuration.class, PythonFunctionInfo.class, RowType.class, RowType.class, RowType.class, FlinkJoinType.class, GeneratedProjection.class);
return (OneInputStreamOperator<RowData, RowData>) ctor.newInstance(pythonConfig, pythonFunctionInfo, inputType, udfInputType, udfOutputType, joinType, ProjectionCodeGenerator.generateProjection(CodeGeneratorContext.apply(config.getTableConfig()), "UdtfInputProjection", inputType, udfInputType, udtfInputOffsets));
} catch (Exception e) {
throw new TableException("Python Table Function Operator constructed failed.", e);
}
}
Aggregations