in paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/PredicateConverter.java [74:194]
public Predicate visit(CallExpression call) {
FunctionDefinition func = call.getFunctionDefinition();
List<Expression> children = call.getChildren();
if (func == BuiltInFunctionDefinitions.AND) {
return PredicateBuilder.and(children.get(0).accept(this), children.get(1).accept(this));
} else if (func == BuiltInFunctionDefinitions.OR) {
return PredicateBuilder.or(children.get(0).accept(this), children.get(1).accept(this));
} else if (func == BuiltInFunctionDefinitions.EQUALS) {
return visitBiFunction(children, builder::equal, builder::equal);
} else if (func == BuiltInFunctionDefinitions.NOT_EQUALS) {
return visitBiFunction(children, builder::notEqual, builder::notEqual);
} else if (func == BuiltInFunctionDefinitions.GREATER_THAN) {
return visitBiFunction(children, builder::greaterThan, builder::lessThan);
} else if (func == BuiltInFunctionDefinitions.GREATER_THAN_OR_EQUAL) {
return visitBiFunction(children, builder::greaterOrEqual, builder::lessOrEqual);
} else if (func == BuiltInFunctionDefinitions.LESS_THAN) {
return visitBiFunction(children, builder::lessThan, builder::greaterThan);
} else if (func == BuiltInFunctionDefinitions.LESS_THAN_OR_EQUAL) {
return visitBiFunction(children, builder::lessOrEqual, builder::greaterOrEqual);
} else if (func == BuiltInFunctionDefinitions.IN) {
FieldReferenceExpression fieldRefExpr =
extractFieldReference(children.get(0)).orElseThrow(UnsupportedExpression::new);
List<Object> literals = new ArrayList<>();
for (int i = 1; i < children.size(); i++) {
literals.add(extractLiteral(fieldRefExpr.getOutputDataType(), children.get(i)));
}
return builder.in(builder.indexOf(fieldRefExpr.getName()), literals);
} else if (func == BuiltInFunctionDefinitions.IS_NULL) {
return extractFieldReference(children.get(0))
.map(FieldReferenceExpression::getName)
.map(builder::indexOf)
.map(builder::isNull)
.orElseThrow(UnsupportedExpression::new);
} else if (func == BuiltInFunctionDefinitions.IS_NOT_NULL) {
return extractFieldReference(children.get(0))
.map(FieldReferenceExpression::getName)
.map(builder::indexOf)
.map(builder::isNotNull)
.orElseThrow(UnsupportedExpression::new);
} else if (func == BuiltInFunctionDefinitions.BETWEEN) {
FieldReferenceExpression fieldRefExpr =
extractFieldReference(children.get(0)).orElseThrow(UnsupportedExpression::new);
return builder.between(
builder.indexOf(fieldRefExpr.getName()), children.get(1), children.get(2));
} else if (func == BuiltInFunctionDefinitions.LIKE) {
FieldReferenceExpression fieldRefExpr =
extractFieldReference(children.get(0)).orElseThrow(UnsupportedExpression::new);
if (fieldRefExpr
.getOutputDataType()
.getLogicalType()
.getTypeRoot()
.getFamilies()
.contains(LogicalTypeFamily.CHARACTER_STRING)) {
String sqlPattern =
Objects.requireNonNull(
extractLiteral(
fieldRefExpr.getOutputDataType(), children.get(1)))
.toString();
String escape =
children.size() <= 2
? null
: Objects.requireNonNull(
extractLiteral(
fieldRefExpr.getOutputDataType(),
children.get(2)))
.toString();
String escapedSqlPattern = sqlPattern;
boolean allowQuick = false;
if (escape == null && !sqlPattern.contains("_")) {
allowQuick = true;
} else if (escape != null) {
if (escape.length() != 1) {
throw new UnsupportedExpression();
}
char escapeChar = escape.charAt(0);
boolean matched = true;
int i = 0;
StringBuilder sb = new StringBuilder();
while (i < sqlPattern.length() && matched) {
char c = sqlPattern.charAt(i);
if (c == escapeChar) {
if (i == (sqlPattern.length() - 1)) {
throw new UnsupportedExpression();
}
char nextChar = sqlPattern.charAt(i + 1);
if (nextChar == '%') {
matched = false;
} else if ((nextChar == '_') || (nextChar == escapeChar)) {
sb.append(nextChar);
i += 1;
} else {
throw new UnsupportedExpression();
}
} else if (c == '_') {
matched = false;
} else {
sb.append(c);
}
i = i + 1;
}
if (matched) {
allowQuick = true;
escapedSqlPattern = sb.toString();
}
}
if (allowQuick) {
Matcher beginMatcher = BEGIN_PATTERN.matcher(escapedSqlPattern);
if (beginMatcher.matches()) {
return builder.startsWith(
builder.indexOf(fieldRefExpr.getName()),
BinaryString.fromString(beginMatcher.group(1)));
}
}
}
}
// TODO is_xxx, between_xxx, similar, in, not_in, not?
throw new UnsupportedExpression();
}