use of org.apache.flink.table.expressions.CallExpression in project flink by apache.
the class FilterUtils method getValue.
private static Comparable<?> getValue(Expression expr, Function<String, Comparable<?>> getter) {
if (expr instanceof ValueLiteralExpression) {
Optional<?> value = ((ValueLiteralExpression) expr).getValueAs(((ValueLiteralExpression) expr).getOutputDataType().getConversionClass());
return (Comparable<?>) value.orElse(null);
}
if (expr instanceof FieldReferenceExpression) {
return getter.apply(((FieldReferenceExpression) expr).getName());
}
if (expr instanceof CallExpression && expr.getChildren().size() == 1) {
Object child = getValue(expr.getChildren().get(0), getter);
FunctionDefinition functionDefinition = ((CallExpression) expr).getFunctionDefinition();
if (functionDefinition.equals(UPPER)) {
return child.toString().toUpperCase();
} else if (functionDefinition.equals(LOWER)) {
return child.toString().toLowerCase();
} else {
throw new UnsupportedOperationException(String.format("Unrecognized function definition: %s.", functionDefinition));
}
}
throw new UnsupportedOperationException(expr + " not supported!");
}
use of org.apache.flink.table.expressions.CallExpression in project flink by apache.
the class OrcFileSystemFilterTest method testApplyPredicate.
@Test
@SuppressWarnings("unchecked")
public void testApplyPredicate() {
List<ResolvedExpression> args = new ArrayList<>();
// equal
FieldReferenceExpression fieldReferenceExpression = new FieldReferenceExpression("long1", DataTypes.BIGINT(), 0, 0);
ValueLiteralExpression valueLiteralExpression = new ValueLiteralExpression(10);
args.add(fieldReferenceExpression);
args.add(valueLiteralExpression);
CallExpression equalExpression = CallExpression.permanent(BuiltInFunctionDefinitions.EQUALS, args, DataTypes.BOOLEAN());
OrcFilters.Predicate predicate1 = OrcFilters.toOrcPredicate(equalExpression);
OrcFilters.Predicate predicate2 = new OrcFilters.Equals("long1", PredicateLeaf.Type.LONG, 10);
assertTrue(predicate1.toString().equals(predicate2.toString()));
// greater than
CallExpression greaterExpression = CallExpression.permanent(BuiltInFunctionDefinitions.GREATER_THAN, args, DataTypes.BOOLEAN());
OrcFilters.Predicate predicate3 = OrcFilters.toOrcPredicate(greaterExpression);
OrcFilters.Predicate predicate4 = new OrcFilters.Not(new OrcFilters.LessThanEquals("long1", PredicateLeaf.Type.LONG, 10));
assertTrue(predicate3.toString().equals(predicate4.toString()));
// less than
CallExpression lessExpression = CallExpression.permanent(BuiltInFunctionDefinitions.LESS_THAN, args, DataTypes.BOOLEAN());
OrcFilters.Predicate predicate5 = OrcFilters.toOrcPredicate(lessExpression);
OrcFilters.Predicate predicate6 = new OrcFilters.LessThan("long1", PredicateLeaf.Type.LONG, 10);
assertTrue(predicate5.toString().equals(predicate6.toString()));
}
use of org.apache.flink.table.expressions.CallExpression in project flink by apache.
the class ValuesOperationFactory method convertToExpectedType.
private Optional<ResolvedExpression> convertToExpectedType(ResolvedExpression sourceExpression, DataType targetDataType, ExpressionResolver.PostResolverFactory postResolverFactory) {
LogicalType sourceLogicalType = sourceExpression.getOutputDataType().getLogicalType();
LogicalType targetLogicalType = targetDataType.getLogicalType();
// if the expression is a literal try converting the literal in place instead of casting
if (sourceExpression instanceof ValueLiteralExpression) {
// Assign a type to a null literal
if (sourceLogicalType.is(NULL)) {
return Optional.of(valueLiteral(null, targetDataType));
}
// Check if the source value class is a valid input conversion class of the target type
// It may happen that a user wanted to use a secondary input conversion class as a value
// for
// a different type than what we derived.
//
// Example: we interpreted 1L as BIGINT, but user wanted to interpret it as a TIMESTAMP
// In this case long is a valid conversion class for TIMESTAMP, but a
// cast from BIGINT to TIMESTAMP is an invalid operation.
Optional<Object> value = ((ValueLiteralExpression) sourceExpression).getValueAs(Object.class);
if (value.isPresent() && targetLogicalType.supportsInputConversion(value.get().getClass())) {
ValueLiteralExpression convertedLiteral = valueLiteral(value.get(), targetDataType.notNull().bridgedTo(value.get().getClass()));
if (targetLogicalType.isNullable()) {
return Optional.of(postResolverFactory.cast(convertedLiteral, targetDataType));
} else {
return Optional.of(convertedLiteral);
}
}
}
if (sourceExpression instanceof CallExpression) {
FunctionDefinition functionDefinition = ((CallExpression) sourceExpression).getFunctionDefinition();
if (functionDefinition == BuiltInFunctionDefinitions.ROW && targetLogicalType.is(ROW)) {
return convertRowToExpectedType(sourceExpression, (FieldsDataType) targetDataType, postResolverFactory);
} else if (functionDefinition == BuiltInFunctionDefinitions.ARRAY && targetLogicalType.is(ARRAY)) {
return convertArrayToExpectedType(sourceExpression, (CollectionDataType) targetDataType, postResolverFactory);
} else if (functionDefinition == BuiltInFunctionDefinitions.MAP && targetLogicalType.is(MAP)) {
return convertMapToExpectedType(sourceExpression, (KeyValueDataType) targetDataType, postResolverFactory);
}
}
// might know that a certain function will not produce nullable values for a given input
if (supportsExplicitCast(sourceLogicalType.copy(true), targetLogicalType.copy(true))) {
return Optional.of(postResolverFactory.cast(sourceExpression, targetDataType));
} else {
return Optional.empty();
}
}
use of org.apache.flink.table.expressions.CallExpression in project flink by apache.
the class OverConvertRule method convert.
@Override
public Optional<RexNode> convert(CallExpression call, ConvertContext context) {
List<Expression> children = call.getChildren();
if (call.getFunctionDefinition() == BuiltInFunctionDefinitions.OVER) {
FlinkTypeFactory typeFactory = context.getTypeFactory();
Expression agg = children.get(0);
FunctionDefinition def = ((CallExpression) agg).getFunctionDefinition();
boolean isDistinct = BuiltInFunctionDefinitions.DISTINCT == def;
SqlAggFunction aggFunc = agg.accept(new SqlAggFunctionVisitor(context.getRelBuilder()));
RelDataType aggResultType = typeFactory.createFieldTypeFromLogicalType(fromDataTypeToLogicalType(((ResolvedExpression) agg).getOutputDataType()));
// assemble exprs by agg children
List<RexNode> aggExprs = agg.getChildren().stream().map(child -> {
if (isDistinct) {
return context.toRexNode(child.getChildren().get(0));
} else {
return context.toRexNode(child);
}
}).collect(Collectors.toList());
// assemble order by key
Expression orderKeyExpr = children.get(1);
Set<SqlKind> kinds = new HashSet<>();
RexNode collationRexNode = createCollation(context.toRexNode(orderKeyExpr), RelFieldCollation.Direction.ASCENDING, null, kinds);
ImmutableList<RexFieldCollation> orderKey = ImmutableList.of(new RexFieldCollation(collationRexNode, kinds));
// assemble partition by keys
List<RexNode> partitionKeys = children.subList(4, children.size()).stream().map(context::toRexNode).collect(Collectors.toList());
// assemble bounds
Expression preceding = children.get(2);
boolean isPhysical = fromDataTypeToLogicalType(((ResolvedExpression) preceding).getOutputDataType()).is(LogicalTypeRoot.BIGINT);
Expression following = children.get(3);
RexWindowBound lowerBound = createBound(context, preceding, SqlKind.PRECEDING);
RexWindowBound upperBound = createBound(context, following, SqlKind.FOLLOWING);
// build RexOver
return Optional.of(context.getRelBuilder().getRexBuilder().makeOver(aggResultType, aggFunc, aggExprs, partitionKeys, orderKey, lowerBound, upperBound, isPhysical, true, false, isDistinct));
}
return Optional.empty();
}
use of org.apache.flink.table.expressions.CallExpression in project flink by apache.
the class InConverter method convert.
@Override
public RexNode convert(CallExpression call, CallExpressionConvertRule.ConvertContext context) {
checkArgument(call, call.getChildren().size() > 1);
Expression headExpr = call.getChildren().get(1);
if (headExpr instanceof TableReferenceExpression) {
QueryOperation tableOperation = ((TableReferenceExpression) headExpr).getQueryOperation();
RexNode child = context.toRexNode(call.getChildren().get(0));
return RexSubQuery.in(((FlinkRelBuilder) context.getRelBuilder()).queryOperation(tableOperation).build(), ImmutableList.of(child));
} else {
List<RexNode> child = toRexNodes(context, call.getChildren());
return context.getRelBuilder().getRexBuilder().makeIn(child.get(0), child.subList(1, child.size()));
}
}
Aggregations