use of org.apache.flink.table.functions.FunctionDefinition in project flink by apache.
the class FunctionCatalogOperatorTable method verifyFunctionKind.
/**
* Verifies which kinds of functions are allowed to be returned from the catalog given the
* context information.
*/
private boolean verifyFunctionKind(@Nullable SqlFunctionCategory category, ContextResolvedFunction resolvedFunction) {
final FunctionDefinition definition = resolvedFunction.getDefinition();
// built-in functions without implementation are handled separately
if (definition instanceof BuiltInFunctionDefinition) {
final BuiltInFunctionDefinition builtInFunction = (BuiltInFunctionDefinition) definition;
if (!builtInFunction.hasRuntimeImplementation()) {
return false;
}
}
final FunctionKind kind = definition.getKind();
if (kind == FunctionKind.TABLE) {
return true;
} else if (kind == FunctionKind.SCALAR || kind == FunctionKind.AGGREGATE || kind == FunctionKind.TABLE_AGGREGATE) {
if (category != null && category.isTableFunction()) {
throw new ValidationException(String.format("Function '%s' cannot be used as a table function.", resolvedFunction));
}
return true;
}
return false;
}
use of org.apache.flink.table.functions.FunctionDefinition in project flink by apache.
the class SqlAggFunctionVisitor method createSqlAggFunction.
private SqlAggFunction createSqlAggFunction(CallExpression call) {
final FunctionDefinition definition = call.getFunctionDefinition();
// legacy
if (definition instanceof AggregateFunctionDefinition) {
return createLegacySqlAggregateFunction(call.getFunctionIdentifier().orElse(null), (AggregateFunctionDefinition) definition);
} else if (definition instanceof TableAggregateFunctionDefinition) {
return createLegacySqlTableAggregateFunction(call.getFunctionIdentifier().orElse(null), (TableAggregateFunctionDefinition) definition);
}
// new stack
final DataTypeFactory dataTypeFactory = ShortcutUtils.unwrapContext(relBuilder).getCatalogManager().getDataTypeFactory();
final TypeInference typeInference = definition.getTypeInference(dataTypeFactory);
return BridgingSqlAggFunction.of(dataTypeFactory, ShortcutUtils.unwrapTypeFactory(relBuilder), SqlKind.OTHER_FUNCTION, ContextResolvedFunction.fromCallExpression(call), typeInference);
}
use of org.apache.flink.table.functions.FunctionDefinition in project flink by apache.
the class FunctionDefinitionConvertRule method convert.
@Override
public Optional<RexNode> convert(CallExpression call, ConvertContext context) {
final FunctionDefinition definition = call.getFunctionDefinition();
// built-in functions without implementation are handled separately
if (definition instanceof BuiltInFunctionDefinition) {
final BuiltInFunctionDefinition builtInFunction = (BuiltInFunctionDefinition) definition;
if (!builtInFunction.hasRuntimeImplementation()) {
return Optional.empty();
}
}
final TypeInference typeInference = definition.getTypeInference(context.getDataTypeFactory());
if (typeInference.getOutputTypeStrategy() == TypeStrategies.MISSING) {
return Optional.empty();
}
switch(definition.getKind()) {
case SCALAR:
case TABLE:
final List<RexNode> args = call.getChildren().stream().map(context::toRexNode).collect(Collectors.toList());
final BridgingSqlFunction sqlFunction = BridgingSqlFunction.of(context.getDataTypeFactory(), context.getTypeFactory(), SqlKind.OTHER_FUNCTION, ContextResolvedFunction.fromCallExpression(call), typeInference);
return Optional.of(context.getRelBuilder().call(sqlFunction, args));
default:
return Optional.empty();
}
}
use of org.apache.flink.table.functions.FunctionDefinition in project flink by apache.
the class OverConvertRule method createBound.
private RexWindowBound createBound(ConvertContext context, Expression bound, SqlKind sqlKind) {
if (bound instanceof CallExpression) {
CallExpression callExpr = (CallExpression) bound;
FunctionDefinition func = callExpr.getFunctionDefinition();
if (BuiltInFunctionDefinitions.UNBOUNDED_ROW.equals(func) || BuiltInFunctionDefinitions.UNBOUNDED_RANGE.equals(func)) {
SqlNode unbounded = sqlKind.equals(SqlKind.PRECEDING) ? SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO) : SqlWindow.createUnboundedFollowing(SqlParserPos.ZERO);
return RexWindowBound.create(unbounded, null);
} else if (BuiltInFunctionDefinitions.CURRENT_ROW.equals(func) || BuiltInFunctionDefinitions.CURRENT_RANGE.equals(func)) {
SqlNode currentRow = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
return RexWindowBound.create(currentRow, null);
} else {
throw new IllegalArgumentException("Unexpected expression: " + bound);
}
} else if (bound instanceof ValueLiteralExpression) {
RelDataType returnType = context.getTypeFactory().createFieldTypeFromLogicalType(new DecimalType(true, 19, 0));
SqlOperator sqlOperator = new SqlPostfixOperator(sqlKind.name(), sqlKind, 2, new OrdinalReturnTypeInference(0), null, null);
SqlNode[] operands = new SqlNode[] { SqlLiteral.createExactNumeric("1", SqlParserPos.ZERO) };
SqlNode node = new SqlBasicCall(sqlOperator, operands, SqlParserPos.ZERO);
ValueLiteralExpression literalExpr = (ValueLiteralExpression) bound;
RexNode literalRexNode = literalExpr.getValueAs(BigDecimal.class).map(v -> context.getRelBuilder().literal(v)).orElse(context.getRelBuilder().literal(extractValue(literalExpr, Object.class)));
List<RexNode> expressions = new ArrayList<>();
expressions.add(literalRexNode);
RexNode rexNode = context.getRelBuilder().getRexBuilder().makeCall(returnType, sqlOperator, expressions);
return RexWindowBound.create(node, rexNode);
} else {
throw new TableException("Unexpected expression: " + bound);
}
}
use of org.apache.flink.table.functions.FunctionDefinition in project flink by apache.
the class LegacyScalarFunctionConvertRule method convert.
@Override
public Optional<RexNode> convert(CallExpression call, ConvertContext context) {
FunctionDefinition def = call.getFunctionDefinition();
if (def instanceof ScalarFunctionDefinition) {
ScalarFunction scalaFunc = ((ScalarFunctionDefinition) def).getScalarFunction();
FunctionIdentifier identifier = call.getFunctionIdentifier().orElse(FunctionIdentifier.of(generateInlineFunctionName(scalaFunc)));
SqlFunction sqlFunction = UserDefinedFunctionUtils.createScalarSqlFunction(identifier, scalaFunc.toString(), scalaFunc, context.getTypeFactory());
return Optional.of(context.getRelBuilder().call(sqlFunction, toRexNodes(context, call.getChildren())));
}
return Optional.empty();
}
Aggregations