This is an automated email from the ASF dual-hosted git repository.
zykkk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 1c142309a6 [refactor](jdbc catalog) refactor JdbcFunctionPushDownRule
(#23826)
1c142309a6 is described below
commit 1c142309a6e69a78c4a3db7a336c40ffccd69e47
Author: zy-kkk <[email protected]>
AuthorDate: Fri Sep 15 22:16:07 2023 +0800
[refactor](jdbc catalog) refactor JdbcFunctionPushDownRule (#23826)
1. Change from using string matching function to using Expr matching
2. Replace the `nvl` function with `ifnull` when pushed down to MySQL
3. Adapt ClickHouse's `from_unixtime` function to push down
4. Non-function filtering can still be pushed down when
`enable_func_pushdown` is set to false
---
.../docker-compose/clickhouse/clickhouse.yaml.tpl | 2 +-
.../clickhouse/init/03-create-table.sql | 8 ++
.../docker-compose/clickhouse/init/04-insert.sql | 3 +
.../external/jdbc/JdbcFunctionPushDownRule.java | 123 ++++++++++++++++++---
.../doris/planner/external/jdbc/JdbcScanNode.java | 60 +++++++---
.../doris/planner/external/odbc/OdbcScanNode.java | 15 ++-
.../jdbc/test_clickhouse_jdbc_catalog.out | Bin 2766 -> 2782 bytes
.../jdbc/test_mysql_jdbc_catalog.out | 46 ++++----
.../jdbc/test_clickhouse_jdbc_catalog.groovy | 9 ++
.../jdbc/test_mysql_jdbc_catalog.groovy | 61 ++++++++--
10 files changed, 264 insertions(+), 63 deletions(-)
diff --git a/docker/thirdparties/docker-compose/clickhouse/clickhouse.yaml.tpl
b/docker/thirdparties/docker-compose/clickhouse/clickhouse.yaml.tpl
index 3832680dea..6e34c459be 100644
--- a/docker/thirdparties/docker-compose/clickhouse/clickhouse.yaml.tpl
+++ b/docker/thirdparties/docker-compose/clickhouse/clickhouse.yaml.tpl
@@ -19,7 +19,7 @@ version: "2.1"
services:
doris--clickhouse:
- image: "clickhouse/clickhouse-server:latest"
+ image: "clickhouse/clickhouse-server:23.3"
restart: always
environment:
CLICKHOUSE_PASSWORD: 123456
diff --git
a/docker/thirdparties/docker-compose/clickhouse/init/03-create-table.sql
b/docker/thirdparties/docker-compose/clickhouse/init/03-create-table.sql
index c13fac5cf9..46d2e6ffc3 100644
--- a/docker/thirdparties/docker-compose/clickhouse/init/03-create-table.sql
+++ b/docker/thirdparties/docker-compose/clickhouse/init/03-create-table.sql
@@ -131,3 +131,11 @@ CREATE TABLE doris_test.final_test
)
ENGINE = ReplacingMergeTree
ORDER BY key;
+
+CREATE TABLE doris_test.ts
+(
+ id Int64,
+ ts UInt64
+)
+ENGINE = MergeTree
+ORDER BY id;
\ No newline at end of file
diff --git a/docker/thirdparties/docker-compose/clickhouse/init/04-insert.sql
b/docker/thirdparties/docker-compose/clickhouse/init/04-insert.sql
index 69c2ebd25f..c5e83eefe0 100644
--- a/docker/thirdparties/docker-compose/clickhouse/init/04-insert.sql
+++ b/docker/thirdparties/docker-compose/clickhouse/init/04-insert.sql
@@ -39,3 +39,6 @@ INSERT INTO doris_test.json VALUES ('1','{"a": 1, "b": { "c":
2, "d": [1, 2, 3]
INSERT INTO doris_test.final_test Values (1, 'first');
INSERT INTO doris_test.final_test Values (1, 'second');
+INSERT INTO doris_test.ts values (1,1694438743);
+
+
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcFunctionPushDownRule.java
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcFunctionPushDownRule.java
index bac9d62dbe..d1a44cb700 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcFunctionPushDownRule.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcFunctionPushDownRule.java
@@ -17,33 +17,130 @@
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.thrift.TOdbcTableType;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Map;
import java.util.TreeSet;
+import java.util.function.Predicate;
public class JdbcFunctionPushDownRule {
- private static final TreeSet<String> UNSUPPORTED_MYSQL_FUNCTIONS = new
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+ private static final Logger LOG =
LogManager.getLogger(JdbcFunctionPushDownRule.class);
+ private static final TreeSet<String> MYSQL_UNSUPPORTED_FUNCTIONS = new
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ MYSQL_UNSUPPORTED_FUNCTIONS.add("date_trunc");
+ MYSQL_UNSUPPORTED_FUNCTIONS.add("money_format");
+ }
+
+ private static final TreeSet<String> CLICKHOUSE_SUPPORTED_FUNCTIONS = new
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ CLICKHOUSE_SUPPORTED_FUNCTIONS.add("from_unixtime");
+ }
+
+ private static boolean isMySQLFunctionUnsupported(String functionName) {
+ return
MYSQL_UNSUPPORTED_FUNCTIONS.contains(functionName.toLowerCase());
+ }
+
+ private static boolean isClickHouseFunctionUnsupported(String
functionName) {
+ return
!CLICKHOUSE_SUPPORTED_FUNCTIONS.contains(functionName.toLowerCase());
+ }
+
+
+ private static final Map<String, String> REPLACE_MYSQL_FUNCTIONS =
Maps.newHashMap();
+
+ static {
+ REPLACE_MYSQL_FUNCTIONS.put("nvl", "ifnull");
+ }
+
+ 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 {
- UNSUPPORTED_MYSQL_FUNCTIONS.add("date_trunc");
- UNSUPPORTED_MYSQL_FUNCTIONS.add("money_format");
+ REPLACE_CLICKHOUSE_FUNCTIONS.put("from_unixtime", "FROM_UNIXTIME");
+ }
+
+ private static boolean isReplaceClickHouseFunctions(String functionName) {
+ return
REPLACE_CLICKHOUSE_FUNCTIONS.containsKey(functionName.toLowerCase());
}
- public static boolean isUnsupportedFunctions(TOdbcTableType tableType,
String filter) {
- if (tableType.equals(TOdbcTableType.MYSQL)) {
- return isMySQLUnsupportedFunctions(filter);
+ public static Expr processFunctions(TOdbcTableType tableType, Expr expr,
List<String> errors) {
+ if (tableType == null || expr == null) {
+ return expr;
+ }
+
+ Predicate<String> checkFunction;
+ Predicate<String> replaceFunction;
+
+ if (TOdbcTableType.MYSQL.equals(tableType)) {
+ replaceFunction =
JdbcFunctionPushDownRule::isReplaceMysqlFunctions;
+ checkFunction =
JdbcFunctionPushDownRule::isMySQLFunctionUnsupported;
+ } else if (TOdbcTableType.CLICKHOUSE.equals(tableType)) {
+ replaceFunction =
JdbcFunctionPushDownRule::isReplaceClickHouseFunctions;
+ checkFunction =
JdbcFunctionPushDownRule::isClickHouseFunctionUnsupported;
} else {
- return false;
+ return expr;
}
+
+ return processFunctionsRecursively(expr, checkFunction,
replaceFunction, errors, tableType);
}
- private static boolean isMySQLUnsupportedFunctions(String filter) {
- for (String func : UNSUPPORTED_MYSQL_FUNCTIONS) {
- if (filter.contains(func)) {
- return true;
+ private static Expr processFunctionsRecursively(Expr expr,
Predicate<String> checkFunction,
+ Predicate<String> replaceFunction, List<String> errors,
TOdbcTableType tableType) {
+ if (expr instanceof FunctionCallExpr) {
+ FunctionCallExpr functionCallExpr = (FunctionCallExpr) expr;
+ String func = functionCallExpr.getFnName().getFunction();
+
+ Preconditions.checkArgument(!func.isEmpty(), "function can not be
empty");
+
+ func = replaceFunctionNameIfNecessary(func, replaceFunction,
functionCallExpr, tableType);
+
+ if (!func.isEmpty() && checkFunction.test(func)) {
+ String errMsg = "Unsupported function: " + func + " in expr: "
+ expr.toMySql()
+ + " in JDBC Table Type: " + tableType;
+ LOG.warn(errMsg);
+ errors.add(errMsg);
}
}
- return false;
+
+ List<Expr> children = expr.getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ Expr child = children.get(i);
+ Expr newChild = processFunctionsRecursively(child, checkFunction,
replaceFunction, errors, tableType);
+ expr.setChild(i, newChild);
+ }
+
+ return expr;
}
-}
+ private static String replaceFunctionNameIfNecessary(String func,
Predicate<String> replaceFunction,
+ FunctionCallExpr functionCallExpr, TOdbcTableType tableType) {
+ if (replaceFunction.test(func)) {
+ String newFunc;
+ if (TOdbcTableType.MYSQL.equals(tableType)) {
+ newFunc = REPLACE_MYSQL_FUNCTIONS.get(func.toLowerCase());
+ } else if (TOdbcTableType.CLICKHOUSE.equals(tableType)) {
+ newFunc = REPLACE_CLICKHOUSE_FUNCTIONS.get(func);
+ } else {
+ newFunc = null;
+ }
+ if (newFunc != null) {
+
functionCallExpr.setFnName(FunctionName.createBuiltinName(newFunc));
+ func = functionCallExpr.getFnName().getFunction();
+ }
+ }
+ return func;
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
index 94b6aeb160..ccba1a165f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
@@ -19,6 +19,7 @@ package org.apache.doris.planner.external.jdbc;
import org.apache.doris.analysis.Analyzer;
import org.apache.doris.analysis.BinaryPredicate;
+import org.apache.doris.analysis.BoolLiteral;
import org.apache.doris.analysis.DateLiteral;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.ExprSubstitutionMap;
@@ -113,7 +114,7 @@ public class JdbcScanNode extends ExternalScanNode {
break;
}
}
- //clean conjusts cause graph sannnode no need conjuncts
+ // clean conjusts cause graph sannnode no need conjuncts
conjuncts = Lists.newArrayList();
}
@@ -133,19 +134,32 @@ public class JdbcScanNode extends ExternalScanNode {
}
ArrayList<Expr> conjunctsList = Expr.cloneList(conjuncts, sMap);
+ List<String> errors = Lists.newArrayList();
+ List<Expr> pushDownConjuncts =
collectConjunctsToPushDown(conjunctsList, errors);
+
+ for (Expr individualConjunct : pushDownConjuncts) {
+ String filter = conjunctExprToString(jdbcType, individualConjunct);
+ filters.add(filter);
+ conjuncts.remove(individualConjunct);
+ }
+ }
+
+ private List<Expr> collectConjunctsToPushDown(List<Expr> conjunctsList,
List<String> errors) {
+ List<Expr> pushDownConjuncts = new ArrayList<>();
for (Expr p : conjunctsList) {
if (shouldPushDownConjunct(jdbcType, p)) {
- String filter = conjunctExprToString(jdbcType, p);
- if (filter.equals("TRUE")) {
- filter = "1 = 1";
- }
- if (JdbcFunctionPushDownRule.isUnsupportedFunctions(jdbcType,
filter)) {
- continue;
+ List<Expr> individualConjuncts = p.getConjuncts();
+ for (Expr individualConjunct : individualConjuncts) {
+ Expr newp =
JdbcFunctionPushDownRule.processFunctions(jdbcType, individualConjunct, errors);
+ if (!errors.isEmpty()) {
+ errors.clear();
+ continue;
+ }
+ pushDownConjuncts.add(newp);
}
- filters.add(filter);
- conjuncts.remove(p);
}
}
+ return pushDownConjuncts;
}
private void createJdbcColumns() {
@@ -282,7 +296,7 @@ public class JdbcScanNode extends ExternalScanNode {
@Override
public int getNumInstances() {
return
ConnectContext.get().getSessionVariable().getEnablePipelineEngine()
- ?
ConnectContext.get().getSessionVariable().getParallelExecInstanceNum() : 1;
+ ?
ConnectContext.get().getSessionVariable().getParallelExecInstanceNum() : 1;
}
@Override
@@ -292,17 +306,22 @@ public class JdbcScanNode extends ExternalScanNode {
tbl.getId(), -1L);
}
- // Now some database have different function call like doris, now doris do
not
- // push down the function call except MYSQL
- public static boolean shouldPushDownConjunct(TOdbcTableType tableType,
Expr expr) {
- if (!tableType.equals(TOdbcTableType.MYSQL)) {
- List<FunctionCallExpr> fnExprList = Lists.newArrayList();
- expr.collect(FunctionCallExpr.class, fnExprList);
- if (!fnExprList.isEmpty()) {
+ private static boolean shouldPushDownConjunct(TOdbcTableType tableType,
Expr expr) {
+ if (containsFunctionCallExpr(expr)) {
+ if (tableType.equals(TOdbcTableType.MYSQL) ||
tableType.equals(TOdbcTableType.CLICKHOUSE)) {
+ return Config.enable_func_pushdown;
+ } else {
return false;
}
+ } else {
+ return true;
}
- return Config.enable_func_pushdown;
+ }
+
+ private static boolean containsFunctionCallExpr(Expr expr) {
+ List<FunctionCallExpr> fnExprList = Lists.newArrayList();
+ expr.collect(FunctionCallExpr.class, fnExprList);
+ return !fnExprList.isEmpty();
}
public static String conjunctExprToString(TOdbcTableType tableType, Expr
expr) {
@@ -338,6 +357,11 @@ public class JdbcScanNode extends ExternalScanNode {
}
}
+ // only for old planner
+ if (expr.contains(BoolLiteral.class) &&
expr.getStringValue().equals("1") && expr.getChildren().isEmpty()) {
+ return "1 = 1";
+ }
+
return expr.toMySql();
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
index 0f27e9da58..bf4e835e4f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
@@ -20,6 +20,7 @@ package org.apache.doris.planner.external.odbc;
import org.apache.doris.analysis.Analyzer;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.ExprSubstitutionMap;
+import org.apache.doris.analysis.FunctionCallExpr;
import org.apache.doris.analysis.SlotDescriptor;
import org.apache.doris.analysis.SlotRef;
import org.apache.doris.analysis.TupleDescriptor;
@@ -28,6 +29,7 @@ import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.JdbcTable;
import org.apache.doris.catalog.OdbcTable;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Config;
import org.apache.doris.common.UserException;
import org.apache.doris.planner.PlanNodeId;
import org.apache.doris.planner.external.ExternalScanNode;
@@ -181,7 +183,7 @@ public class OdbcScanNode extends ExternalScanNode {
}
ArrayList<Expr> odbcConjuncts = Expr.cloneList(conjuncts, sMap);
for (Expr p : odbcConjuncts) {
- if (JdbcScanNode.shouldPushDownConjunct(odbcType, p)) {
+ if (shouldPushDownConjunct(odbcType, p)) {
String filter = JdbcScanNode.conjunctExprToString(odbcType, p);
filters.add(filter);
conjuncts.remove(p);
@@ -224,4 +226,15 @@ public class OdbcScanNode extends ExternalScanNode {
return
ConnectContext.get().getSessionVariable().getEnablePipelineEngine()
?
ConnectContext.get().getSessionVariable().getParallelExecInstanceNum() : 1;
}
+
+ public static boolean shouldPushDownConjunct(TOdbcTableType tableType,
Expr expr) {
+ if (!tableType.equals(TOdbcTableType.MYSQL)) {
+ List<FunctionCallExpr> fnExprList = Lists.newArrayList();
+ expr.collect(FunctionCallExpr.class, fnExprList);
+ if (!fnExprList.isEmpty()) {
+ return false;
+ }
+ }
+ return Config.enable_func_pushdown;
+ }
}
diff --git
a/regression-test/data/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.out
b/regression-test/data/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.out
index 0b847974ef..05372e3f0a 100644
Binary files
a/regression-test/data/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.out
and
b/regression-test/data/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.out
differ
diff --git
a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
index 5037157a24..d5cc90fa80 100644
--- a/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
+++ b/regression-test/data/external_table_p0/jdbc/test_mysql_jdbc_catalog.out
@@ -238,29 +238,6 @@ VIEWS
\N
2023-06-17T10:00
--- !filter1 --
-1 6 1 1 2099.18 3 8 1554296.82
68781940.49 d 8 5 0 d a 7 9
-
--- !filter2 --
-1 6 1 1 2099.18 3 8 1554296.82
68781940.49 d 8 5 0 d a 7 9
-2 8 9 8 2900.42 1 6 97486621.73
59634489.39 c 3 2 0 a e 7 4
-3 5 7 3 6276.86 8 9 32758730.38
10260499.72 c 8 1 0 d c 9 2
-4 3 7 5 2449.00 6 3 91359059.28
64743145.92 e 7 8 0 b d 8 4
-5 6 4 5 9137.82 2 7 26526675.70
90098303.36 a 6 7 0 d e 4 1
-6 3 6 8 7601.25 4 9 49117098.47
46499188.80 c 3 3 0 c d 4 8
-7 3 2 8 5297.81 9 3 23753694.20
96930000.64 c 7 2 0 b e 1 5
-8 3 6 7 3683.85 5 7 26056250.91
1127755.43 b 7 6 0 d b 4 7
-9 3 9 1 4785.38 1 5 95199488.12
94869703.42 a 4 4 0 c d 2 4
-
--- !filter3 --
-1 6 1 1 2099.18 3 8 1554296.82
68781940.49 d 8 5 0 d a 7 9
-
--- !date_trunc --
-2023-06-17T10:00
-
--- !money_format --
-1
-
-- !test_insert1 --
doris1 18
@@ -305,3 +282,26 @@ sys
-- !mysql_view --
10086 4294967295 201
+-- !filter1 --
+1 6 1 1 2099.18 3 8 1554296.82
68781940.49 d 8 5 0 d a 7 9
+
+-- !filter2 --
+1 6 1 1 2099.18 3 8 1554296.82
68781940.49 d 8 5 0 d a 7 9
+2 8 9 8 2900.42 1 6 97486621.73
59634489.39 c 3 2 0 a e 7 4
+3 5 7 3 6276.86 8 9 32758730.38
10260499.72 c 8 1 0 d c 9 2
+4 3 7 5 2449.00 6 3 91359059.28
64743145.92 e 7 8 0 b d 8 4
+5 6 4 5 9137.82 2 7 26526675.70
90098303.36 a 6 7 0 d e 4 1
+6 3 6 8 7601.25 4 9 49117098.47
46499188.80 c 3 3 0 c d 4 8
+7 3 2 8 5297.81 9 3 23753694.20
96930000.64 c 7 2 0 b e 1 5
+8 3 6 7 3683.85 5 7 26056250.91
1127755.43 b 7 6 0 d b 4 7
+9 3 9 1 4785.38 1 5 95199488.12
94869703.42 a 4 4 0 c d 2 4
+
+-- !filter3 --
+1 6 1 1 2099.18 3 8 1554296.82
68781940.49 d 8 5 0 d a 7 9
+
+-- !date_trunc --
+2023-06-17T10:00
+
+-- !money_format --
+1
+
diff --git
a/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy
b/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy
index 9c2050ab70..b01f200574 100644
---
a/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy
+++
b/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy
@@ -68,6 +68,15 @@ suite("test_clickhouse_jdbc_catalog",
"p0,external,clickhouse,external_docker,ex
order_qt_final1 """select * from final_test"""
sql "set jdbc_clickhouse_query_final = false;"
order_qt_final2 """select * from final_test"""
+ order_qt_func_push """select * from ts where
from_unixtime(ts,'yyyyMMdd') >= '2022-01-01';"""
+ explain {
+ sql("select * from ts where from_unixtime(ts,'yyyyMMdd') >=
'2022-01-01';")
+ contains """QUERY: SELECT "id", "ts" FROM "doris_test"."ts" WHERE
(FROM_UNIXTIME(ts, '%Y%m%d') >= '2022-01-01')"""
+ }
+ explain {
+ sql("select * from ts where nvl(ts,null) >= '2022-01-01';")
+ contains """QUERY: SELECT "id", "ts" FROM "doris_test"."ts""""
+ }
sql """ drop catalog if exists ${catalog_name} """
}
diff --git
a/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
b/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
index cc8f4fd0fe..3717f17bec 100644
---
a/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
+++
b/regression-test/suites/external_table_p0/jdbc/test_mysql_jdbc_catalog.groovy
@@ -112,11 +112,6 @@ suite("test_mysql_jdbc_catalog",
"p0,external,mysql,external_docker,external_doc
order_qt_auto_default_t """insert into ${auto_default_t}(name)
values('a'); """
order_qt_dt """select * from ${dt}; """
order_qt_dt_null """select * from ${dt_null} order by 1; """
- order_qt_filter1 """select * from ${ex_tb17} where id = 1; """
- order_qt_filter2 """select * from ${ex_tb17} where 1=1 order by 1; """
- order_qt_filter3 """select * from ${ex_tb17} where id = 1 and 1 = 1;
"""
- order_qt_date_trunc """ SELECT timestamp0 from dt where
DATE_TRUNC(date_sub(timestamp0,INTERVAL 9 HOUR),'hour') > '2011-03-03
17:39:05'; """
- order_qt_money_format """ select k8 from test1 where money_format(k8)
= '1.00'; """
// test insert
String uuid1 = UUID.randomUUID().toString();
@@ -238,8 +233,60 @@ suite("test_mysql_jdbc_catalog",
"p0,external,mysql,external_docker,external_doc
"jdbc.driver_url" = "${driver_url}",
"jdbc.driver_class" = "com.mysql.cj.jdbc.Driver");
"""
- qt_mysql_view """ select * from view_catalog.doris_test.mysql_view
order by col_1;"""
- sql """ drop catalog if exists view_catalog; """
+ qt_mysql_view """ select * from view_catalog.doris_test.mysql_view
order by col_1;"""
+ sql """ drop catalog if exists view_catalog; """
+
+ sql """ drop catalog if exists mysql_fun_push_catalog """
+ sql """ CREATE CATALOG mysql_fun_push_catalog PROPERTIES (
+ "type"="jdbc",
+ "jdbc.user"="root",
+ "jdbc.password"="123456",
+ "jdbc.jdbc_url" =
"jdbc:mysql://${externalEnvIp}:${mysql_port}/doris_test?useSSL=false",
+ "jdbc.driver_url" = "${driver_url}",
+ "jdbc.driver_class" = "com.mysql.cj.jdbc.Driver");
+ """
+
+ sql """switch mysql_fun_push_catalog"""
+ sql """ use ${ex_db_name}"""
+ sql """ admin set frontend config ("enable_func_pushdown" = "true");
"""
+ order_qt_filter1 """select * from ${ex_tb17} where id = 1; """
+ order_qt_filter2 """select * from ${ex_tb17} where 1=1 order by 1; """
+ order_qt_filter3 """select * from ${ex_tb17} where id = 1 and 1 = 1;
"""
+ order_qt_date_trunc """ SELECT timestamp0 from dt where
DATE_TRUNC(date_sub(timestamp0,INTERVAL 9 HOUR),'hour') > '2011-03-03
17:39:05'; """
+ order_qt_money_format """ select k8 from test1 where money_format(k8)
= '1.00'; """
+ explain {
+ sql("select k8 from test1 where money_format(k8) = '1.00';")
+
+ contains "QUERY: SELECT `k8` FROM `doris_test`.`test1`"
+ }
+ explain {
+ sql ("SELECT timestamp0 from dt where
DATE_TRUNC(date_sub(timestamp0,INTERVAL 9 HOUR),'hour') > '2011-03-03
17:39:05';")
+
+ contains "QUERY: SELECT `timestamp0` FROM `doris_test`.`dt`"
+ }
+ explain {
+ sql ("SELECT timestamp0 from dt where
DATE_TRUNC(date_sub(timestamp0,INTERVAL 9 HOUR),'hour') > '2011-03-03 17:39:05'
and timestamp0 > '2022-01-01';;")
+
+ contains "QUERY: SELECT `timestamp0` FROM `doris_test`.`dt` WHERE
(timestamp0 > '2022-01-01 00:00:00')"
+ }
+ explain {
+ sql ("select k6, k8 from test1 where nvl(k6, null) = 1;")
+
+ contains "QUERY: SELECT `k6`, `k8` FROM `doris_test`.`test1` WHERE
(ifnull(k6, NULL) = 1)"
+ }
+ explain {
+ sql ("select k6, k8 from test1 where nvl(nvl(k6, null),null) = 1;")
+
+ contains "QUERY: SELECT `k6`, `k8` FROM `doris_test`.`test1` WHERE
(ifnull(ifnull(k6, NULL), NULL) = 1)"
+ }
+ sql """ admin set frontend config ("enable_func_pushdown" = "false");
"""
+ explain {
+ sql ("select k6, k8 from test1 where nvl(k6, null) = 1 and k8 =
1;")
+
+ contains "QUERY: SELECT `k6`, `k8` FROM `doris_test`.`test1` WHERE
(k8 = 1)"
+ }
+ sql """ admin set frontend config ("enable_func_pushdown" = "true");
"""
+ sql """ drop catalog if exists mysql_fun_push_catalog; """
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]