[fix](catalog) fix data_sub/data_add func pushdown in jdbcscan (#30807)

This commit is contained in:
zy-kkk
2024-02-05 22:51:26 +08:00
committed by yiguolei
parent 06ed5780e4
commit 92226c986a
3 changed files with 184 additions and 11 deletions

View File

@ -20,6 +20,7 @@ package org.apache.doris.planner.external.jdbc;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.FunctionCallExpr;
import org.apache.doris.analysis.FunctionName;
import org.apache.doris.analysis.TimestampArithmeticExpr;
import org.apache.doris.catalog.TableIf.TableType;
import org.apache.doris.thrift.TOdbcTableType;
@ -75,10 +76,6 @@ public class JdbcFunctionPushDownRule {
REPLACE_MYSQL_FUNCTIONS.put("to_date", "date");
}
private static boolean isReplaceMysqlFunctions(String functionName) {
return REPLACE_MYSQL_FUNCTIONS.containsKey(functionName.toLowerCase());
}
private static final Map<String, String> REPLACE_CLICKHOUSE_FUNCTIONS = Maps.newHashMap();
static {
@ -86,16 +83,20 @@ public class JdbcFunctionPushDownRule {
REPLACE_CLICKHOUSE_FUNCTIONS.put("unix_timestamp", "toUnixTimestamp");
}
private static boolean isReplaceClickHouseFunctions(String functionName) {
return REPLACE_CLICKHOUSE_FUNCTIONS.containsKey(functionName.toLowerCase());
}
private static final Map<String, String> REPLACE_ORACLE_FUNCTIONS = Maps.newHashMap();
static {
REPLACE_ORACLE_FUNCTIONS.put("ifnull", "nvl");
}
private static boolean isReplaceMysqlFunctions(String functionName) {
return REPLACE_MYSQL_FUNCTIONS.containsKey(functionName.toLowerCase());
}
private static boolean isReplaceClickHouseFunctions(String functionName) {
return REPLACE_CLICKHOUSE_FUNCTIONS.containsKey(functionName.toLowerCase());
}
private static boolean isReplaceOracleFunctions(String functionName) {
return REPLACE_ORACLE_FUNCTIONS.containsKey(functionName.toLowerCase());
}
@ -141,6 +142,8 @@ public class JdbcFunctionPushDownRule {
}
replaceFunctionNameIfNecessary(func, replaceFunction, functionCallExpr, tableType);
expr = replaceGenericFunctionExpr(functionCallExpr, func);
}
List<Expr> children = expr.getChildren();
@ -153,7 +156,7 @@ public class JdbcFunctionPushDownRule {
return expr;
}
private static String replaceFunctionNameIfNecessary(String func, Predicate<String> replaceFunction,
private static void replaceFunctionNameIfNecessary(String func, Predicate<String> replaceFunction,
FunctionCallExpr functionCallExpr, TOdbcTableType tableType) {
if (replaceFunction.test(func)) {
String newFunc;
@ -168,9 +171,48 @@ public class JdbcFunctionPushDownRule {
}
if (newFunc != null) {
functionCallExpr.setFnName(FunctionName.createBuiltinName(newFunc));
func = functionCallExpr.getFnName().getFunction();
}
}
return func;
}
// Function used to convert nereids planner's function to old planner's function
private static Expr replaceGenericFunctionExpr(FunctionCallExpr functionCallExpr, String func) {
Map<String, String> supportedTimeUnits = Maps.newHashMap();
supportedTimeUnits.put("years", "YEAR");
supportedTimeUnits.put("months", "MONTH");
supportedTimeUnits.put("weeks", "WEEK");
supportedTimeUnits.put("days", "DAY");
supportedTimeUnits.put("hours", "HOUR");
supportedTimeUnits.put("minutes", "MINUTE");
supportedTimeUnits.put("seconds", "SECOND");
String baseFuncName = null;
String timeUnit = null;
for (Map.Entry<String, String> entry : supportedTimeUnits.entrySet()) {
if (func.endsWith(entry.getKey() + "_add")) {
baseFuncName = "date_add";
timeUnit = entry.getValue();
break;
} else if (func.endsWith(entry.getKey() + "_sub")) {
baseFuncName = "date_sub";
timeUnit = entry.getValue();
break;
}
}
if (baseFuncName != null && timeUnit != null) {
if (functionCallExpr.getChildren().size() == 2) {
Expr child1 = functionCallExpr.getChild(0);
Expr child2 = functionCallExpr.getChild(1);
return new TimestampArithmeticExpr(
baseFuncName,
child1,
child2,
timeUnit
);
}
}
return functionCallExpr;
}
}