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 2daad2151d [enhancement](jdbc catalog) Add mysql jdbc catalog function 
to filter push-down identification (#21745)
2daad2151d is described below

commit 2daad2151d021d1754be031f0b23b38631d89644
Author: zy-kkk <zhongy...@gmail.com>
AuthorDate: Wed Jul 19 23:48:23 2023 +0800

    [enhancement](jdbc catalog) Add mysql jdbc catalog function to filter 
push-down identification (#21745)
---
 docs/en/docs/lakehouse/multi-catalog/jdbc.md       |  9 +++-
 docs/zh-CN/docs/lakehouse/multi-catalog/jdbc.md    |  9 +++-
 .../apache/doris/analysis/NativeInsertStmt.java    |  2 +-
 .../glue/translator/PhysicalPlanTranslator.java    |  2 +-
 .../java/org/apache/doris/planner/DataSink.java    |  1 +
 .../apache/doris/planner/DistributedPlanner.java   |  2 +
 .../apache/doris/planner/SingleNodePlanner.java    |  2 +
 .../external/jdbc/JdbcFunctionPushDownRule.java    | 49 ++++++++++++++++++++++
 .../planner/{ => external/jdbc}/JdbcScanNode.java  |  6 ++-
 .../planner/{ => external/jdbc}/JdbcTableSink.java |  5 ++-
 .../planner/{ => external/odbc}/OdbcScanNode.java  |  4 +-
 .../planner/{ => external/odbc}/OdbcTableSink.java |  5 ++-
 .../jdbc_catalog_p0/test_mysql_jdbc_catalog.out    |  6 +++
 .../jdbc_catalog_p0/test_mysql_jdbc_catalog.groovy |  8 ++--
 14 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/docs/en/docs/lakehouse/multi-catalog/jdbc.md 
b/docs/en/docs/lakehouse/multi-catalog/jdbc.md
index 70bd3b471f..7a1a73f9d7 100644
--- a/docs/en/docs/lakehouse/multi-catalog/jdbc.md
+++ b/docs/en/docs/lakehouse/multi-catalog/jdbc.md
@@ -89,7 +89,14 @@ In some cases, the keywords in the database might be used as 
the field names. Fo
 
 1. When executing a query like `where dt = '2022-01-01'`, Doris can push down 
these filtering conditions to the external data source, thereby directly 
excluding data that does not meet the conditions at the data source level, 
reducing the number of unqualified Necessary data acquisition and transfer. 
This greatly improves query performance while also reducing the load on 
external data sources.
    
-2. When `enable_func_pushdown` is set to true, the function condition after 
where will also be pushed down to the external data source. Currently, only 
MySQL is supported. If you encounter a function that MySQL does not support, 
you can set this parameter to false.
+2. When `enable_func_pushdown` is set to true, the function condition after 
where will also be pushed down to the external data source. Currently, only 
MySQL is supported. If you encounter a function that MySQL does not support, 
you can set this parameter to false, at present, Doris will automatically 
identify some functions not supported by MySQL to filter the push-down 
conditions, which can be checked by explain sql.
+
+Functions that are currently not pushed down include:
+
+|    MYSQL     |
+|:------------:|
+|  DATE_TRUNC  |
+| MONEY_FORMAT |
 
 ### Line Limit
 
diff --git a/docs/zh-CN/docs/lakehouse/multi-catalog/jdbc.md 
b/docs/zh-CN/docs/lakehouse/multi-catalog/jdbc.md
index 3a92ad5677..7f87668431 100644
--- a/docs/zh-CN/docs/lakehouse/multi-catalog/jdbc.md
+++ b/docs/zh-CN/docs/lakehouse/multi-catalog/jdbc.md
@@ -89,7 +89,14 @@ select * from mysql_catalog.mysql_database.mysql_table where 
k1 > 1000 and k3 ='
 
 1. 当执行类似于 `where dt = '2022-01-01'` 这样的查询时,Doris 
能够将这些过滤条件下推到外部数据源,从而直接在数据源层面排除不符合条件的数据,减少了不必要的数据获取和传输。这大大提高了查询性能,同时也降低了对外部数据源的负载。
    
-2. 当 `enable_func_pushdown` 设置为true,会将 where 之后的函数条件也下推到外部数据源,目前仅支持 MySQL,如遇到 
MySQL 不支持的函数,可以将此参数设置为 false。
+2. 当 `enable_func_pushdown` 设置为true,会将 where 之后的函数条件也下推到外部数据源,目前仅支持 MySQL,如遇到 
MySQL 不支持的函数,可以将此参数设置为 false,目前 Doris 会自动识别部分 MySQL 不支持的函数进行下推条件过滤,可通过 explain 
sql 查看。
+
+目前不会下推的函数有:
+
+|    MYSQL     |
+|:------------:|
+|  DATE_TRUNC  |
+| MONEY_FORMAT |
 
 ### 行数限制
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java
index 2a05ee9e01..8323ff5cf7 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java
@@ -47,8 +47,8 @@ import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.planner.DataPartition;
 import org.apache.doris.planner.DataSink;
 import org.apache.doris.planner.ExportSink;
-import org.apache.doris.planner.JdbcTableSink;
 import org.apache.doris.planner.OlapTableSink;
+import org.apache.doris.planner.external.jdbc.JdbcTableSink;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.rewrite.ExprRewriter;
 import org.apache.doris.service.FrontendOptions;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
index 1f5f90efc1..f1dacc32e6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
@@ -137,7 +137,6 @@ import org.apache.doris.planner.ExchangeNode;
 import org.apache.doris.planner.HashJoinNode;
 import org.apache.doris.planner.HashJoinNode.DistributionMode;
 import org.apache.doris.planner.IntersectNode;
-import org.apache.doris.planner.JdbcScanNode;
 import org.apache.doris.planner.JoinNodeBase;
 import org.apache.doris.planner.MultiCastDataSink;
 import org.apache.doris.planner.MultiCastPlanFragment;
@@ -160,6 +159,7 @@ import org.apache.doris.planner.UnionNode;
 import org.apache.doris.planner.external.HiveScanNode;
 import org.apache.doris.planner.external.hudi.HudiScanNode;
 import org.apache.doris.planner.external.iceberg.IcebergScanNode;
+import org.apache.doris.planner.external.jdbc.JdbcScanNode;
 import org.apache.doris.planner.external.paimon.PaimonScanNode;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.system.SystemInfoService;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/DataSink.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/DataSink.java
index 3e0ff32d06..839301e509 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/DataSink.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/DataSink.java
@@ -24,6 +24,7 @@ import org.apache.doris.catalog.MysqlTable;
 import org.apache.doris.catalog.OdbcTable;
 import org.apache.doris.catalog.Table;
 import org.apache.doris.common.AnalysisException;
+import org.apache.doris.planner.external.odbc.OdbcTableSink;
 import org.apache.doris.thrift.TDataSink;
 import org.apache.doris.thrift.TExplainLevel;
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/DistributedPlanner.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/DistributedPlanner.java
index 6a73952e20..2c236f5f72 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/DistributedPlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/DistributedPlanner.java
@@ -38,6 +38,8 @@ import org.apache.doris.catalog.Table;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Pair;
 import org.apache.doris.common.UserException;
+import org.apache.doris.planner.external.jdbc.JdbcScanNode;
+import org.apache.doris.planner.external.odbc.OdbcScanNode;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.SessionVariable;
 import org.apache.doris.thrift.TPartitionType;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
index eda6c04795..9e041302c2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
@@ -73,6 +73,8 @@ import org.apache.doris.planner.external.HiveScanNode;
 import org.apache.doris.planner.external.MaxComputeScanNode;
 import org.apache.doris.planner.external.hudi.HudiScanNode;
 import org.apache.doris.planner.external.iceberg.IcebergScanNode;
+import org.apache.doris.planner.external.jdbc.JdbcScanNode;
+import org.apache.doris.planner.external.odbc.OdbcScanNode;
 import org.apache.doris.planner.external.paimon.PaimonScanNode;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.rewrite.mvrewrite.MVSelectFailedException;
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
new file mode 100644
index 0000000000..bac9d62dbe
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcFunctionPushDownRule.java
@@ -0,0 +1,49 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.planner.external.jdbc;
+
+import org.apache.doris.thrift.TOdbcTableType;
+
+import java.util.TreeSet;
+
+public class JdbcFunctionPushDownRule {
+    private static final TreeSet<String> UNSUPPORTED_MYSQL_FUNCTIONS = new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+
+    static {
+        UNSUPPORTED_MYSQL_FUNCTIONS.add("date_trunc");
+        UNSUPPORTED_MYSQL_FUNCTIONS.add("money_format");
+    }
+
+    public static boolean isUnsupportedFunctions(TOdbcTableType tableType, 
String filter) {
+        if (tableType.equals(TOdbcTableType.MYSQL)) {
+            return isMySQLUnsupportedFunctions(filter);
+        } else {
+            return false;
+        }
+    }
+
+    private static boolean isMySQLUnsupportedFunctions(String filter) {
+        for (String func : UNSUPPORTED_MYSQL_FUNCTIONS) {
+            if (filter.contains(func)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/JdbcScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
similarity index 98%
rename from fe/fe-core/src/main/java/org/apache/doris/planner/JdbcScanNode.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
index 86cadc847d..3bcbfb8b4d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/JdbcScanNode.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcScanNode.java
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.planner;
+package org.apache.doris.planner.external.jdbc;
 
 import org.apache.doris.analysis.Analyzer;
 import org.apache.doris.analysis.BinaryPredicate;
@@ -36,6 +36,7 @@ import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.UserException;
 import org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
+import org.apache.doris.planner.PlanNodeId;
 import org.apache.doris.planner.external.ExternalScanNode;
 import org.apache.doris.statistics.StatisticalType;
 import org.apache.doris.statistics.StatsRecursiveDerive;
@@ -137,6 +138,9 @@ public class JdbcScanNode extends ExternalScanNode {
                 if (filter.equals("TRUE")) {
                     filter = "1 = 1";
                 }
+                if (JdbcFunctionPushDownRule.isUnsupportedFunctions(jdbcType, 
filter)) {
+                    continue;
+                }
                 filters.add(filter);
                 conjuncts.remove(p);
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/JdbcTableSink.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcTableSink.java
similarity index 96%
rename from fe/fe-core/src/main/java/org/apache/doris/planner/JdbcTableSink.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcTableSink.java
index ae99a53997..263860f1e7 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/JdbcTableSink.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/jdbc/JdbcTableSink.java
@@ -15,9 +15,12 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.planner;
+package org.apache.doris.planner.external.jdbc;
 
 import org.apache.doris.catalog.JdbcTable;
+import org.apache.doris.planner.DataPartition;
+import org.apache.doris.planner.DataSink;
+import org.apache.doris.planner.PlanNodeId;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.thrift.TDataSink;
 import org.apache.doris.thrift.TDataSinkType;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/OdbcScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
similarity index 98%
rename from fe/fe-core/src/main/java/org/apache/doris/planner/OdbcScanNode.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
index 07b2d3775b..2bac81218f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/OdbcScanNode.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcScanNode.java
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.planner;
+package org.apache.doris.planner.external.odbc;
 
 import org.apache.doris.analysis.Analyzer;
 import org.apache.doris.analysis.Expr;
@@ -29,7 +29,9 @@ import org.apache.doris.catalog.JdbcTable;
 import org.apache.doris.catalog.OdbcTable;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.UserException;
+import org.apache.doris.planner.PlanNodeId;
 import org.apache.doris.planner.external.ExternalScanNode;
+import org.apache.doris.planner.external.jdbc.JdbcScanNode;
 import org.apache.doris.statistics.StatisticalType;
 import org.apache.doris.statistics.StatsRecursiveDerive;
 import org.apache.doris.statistics.query.StatsDelta;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/OdbcTableSink.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcTableSink.java
similarity index 94%
rename from fe/fe-core/src/main/java/org/apache/doris/planner/OdbcTableSink.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcTableSink.java
index 0fbe85ea32..8778f06026 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/OdbcTableSink.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/external/odbc/OdbcTableSink.java
@@ -15,10 +15,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.planner;
+package org.apache.doris.planner.external.odbc;
 
 import org.apache.doris.catalog.JdbcTable;
 import org.apache.doris.catalog.OdbcTable;
+import org.apache.doris.planner.DataPartition;
+import org.apache.doris.planner.DataSink;
+import org.apache.doris.planner.PlanNodeId;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.thrift.TDataSink;
 import org.apache.doris.thrift.TDataSinkType;
diff --git a/regression-test/data/jdbc_catalog_p0/test_mysql_jdbc_catalog.out 
b/regression-test/data/jdbc_catalog_p0/test_mysql_jdbc_catalog.out
index f04589e6a2..7177d429e8 100644
--- a/regression-test/data/jdbc_catalog_p0/test_mysql_jdbc_catalog.out
+++ b/regression-test/data/jdbc_catalog_p0/test_mysql_jdbc_catalog.out
@@ -255,6 +255,12 @@ VIEWS
 -- !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
 
diff --git 
a/regression-test/suites/jdbc_catalog_p0/test_mysql_jdbc_catalog.groovy 
b/regression-test/suites/jdbc_catalog_p0/test_mysql_jdbc_catalog.groovy
index 28f8bfa4a7..2e2da519c6 100644
--- a/regression-test/suites/jdbc_catalog_p0/test_mysql_jdbc_catalog.groovy
+++ b/regression-test/suites/jdbc_catalog_p0/test_mysql_jdbc_catalog.groovy
@@ -62,7 +62,7 @@ suite("test_mysql_jdbc_catalog", "p0") {
             "driver_url" = 
"https://doris-community-test-1308700295.cos.ap-hongkong.myqcloud.com/jdbc_driver/mysql-connector-java-8.0.25.jar";,
             "driver_class" = "com.mysql.cj.jdbc.Driver"
         );"""
-        
+
         sql  """ drop table if exists ${inDorisTable} """
         sql  """
               CREATE TABLE ${inDorisTable} (
@@ -108,6 +108,8 @@ suite("test_mysql_jdbc_catalog", "p0") {
         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();
@@ -138,7 +140,7 @@ suite("test_mysql_jdbc_catalog", "p0") {
             "driver_class" = "com.mysql.cj.jdbc.Driver",
             "only_specified_database" = "true"
         );"""
-        
+
         sql """switch ${catalog_name}"""
 
         qt_specified_database_1   """ show databases; """
@@ -156,7 +158,7 @@ suite("test_mysql_jdbc_catalog", "p0") {
             "only_specified_database" = "true",
             "include_database_list" = "doris_test"
         );"""
-        
+
         sql """switch ${catalog_name}"""
 
         qt_specified_database_2   """ show databases; """


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to