From 2d869916f4de9347351f8a1faac2d276005ad095 Mon Sep 17 00:00:00 2001 From: zhanggougou <15651908511@163.com> Date: Thu, 24 Apr 2025 17:05:41 +0800 Subject: [PATCH] =?UTF-8?q?[fire-1222]=20=E5=AE=8C=E5=96=84JDBC=E8=A1=80?= =?UTF-8?q?=E7=BC=98=E8=A7=A3=E6=9E=90=EF=BC=8C=E6=94=AF=E6=8C=81=E6=9B=B4?= =?UTF-8?q?=E5=A4=9ASQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/zto/fire/common/util/SQLUtils.scala | 39 ++++++++++++------- .../zto/fire/common/util/SQLUtilsTest.scala | 34 ++++++++++++++++ 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/fire-common/src/main/scala/com/zto/fire/common/util/SQLUtils.scala b/fire-common/src/main/scala/com/zto/fire/common/util/SQLUtils.scala index 3db5554..a00e6cf 100644 --- a/fire-common/src/main/scala/com/zto/fire/common/util/SQLUtils.scala +++ b/fire-common/src/main/scala/com/zto/fire/common/util/SQLUtils.scala @@ -302,26 +302,35 @@ object SQLUtils extends Logging { /** * 解析SelectBody结构中的血缘信息 + * with语法暂不支持解析 */ private def parseSelectBodyLineage(body: SelectBody, tables: JHashSet[(JString, Operation)]): Unit = { - if (body.isInstanceOf[PlainSelect]) { - val plainSelect = body.asInstanceOf[PlainSelect] - val fromItem = plainSelect.getFromItem - if (fromItem != null && fromItem.isInstanceOf[Table]) { - tables.add((this.getTableName(fromItem.asInstanceOf[Table]), Operation.SELECT)) - } - - val joins = plainSelect.getJoins - if (joins != null && joins.nonEmpty) { - joins.filter(t => t != null && t.getRightItem != null).foreach(join => { - if (join.getRightItem.isInstanceOf[Table]) { - tables.add((this.getTableName(join.getRightItem.asInstanceOf[Table]), Operation.SELECT)) - } - }) - } + body match { + case plainSelect: PlainSelect => + val fromItem = plainSelect.getFromItem + processFromItem(fromItem, tables) + + val joins = plainSelect.getJoins + if (joins != null && joins.nonEmpty) { + joins.filter(t => t != null && t.getRightItem != null).foreach(join => { + processFromItem(join.getRightItem, tables) + }) + } + case otherItem => this.logWarning(s"子查询暂不支持解析: ${otherItem.getClass.getName}") } } + /** + * 递归解析子查询中的血缘信息 + */ + private def processFromItem(item: FromItem, tables: JHashSet[(JString, Operation)]): Unit = item match { + case table: Table => + tables.add((getTableName(table), Operation.SELECT)) + case subSelect: SubSelect => + parseSelectBodyLineage(subSelect.getSelectBody, tables) + case otherItem => this.logWarning(s"Item暂不支持解析: ${otherItem.getClass.getName}") + } + /** * 只解析使用占位符的字段 */ diff --git a/fire-common/src/test/scala/com/zto/fire/common/util/SQLUtilsTest.scala b/fire-common/src/test/scala/com/zto/fire/common/util/SQLUtilsTest.scala index 17ab2b3..072d998 100644 --- a/fire-common/src/test/scala/com/zto/fire/common/util/SQLUtilsTest.scala +++ b/fire-common/src/test/scala/com/zto/fire/common/util/SQLUtilsTest.scala @@ -127,4 +127,38 @@ class SQLUtilsTest { val mergeColumns = SQLUtils.parsePlaceholder(merge) assert("biz_no,appeal_no,postal_bill_code,postal_category_code,postal_create_time,appeal_no,postal_create_time,biz_no,appeal_no,postal_category_code".equals(mergeColumns.mkString(",")), "merge语句解析异常") } + + @Test + def testSelectParse(): Unit = { + var sql = "select batchNumber from rt_zto_truck_p2p" + var jdbcLineages = SQLUtils.parseLineage(sql) + assert("rt_zto_truck_p2p".equals(jdbcLineages.map(_._1).mkString(",")), "基础select语句解析异常") + + //子查询 + sql = "select batchNumber from ( select t.batch_number as batchNumber from rt_zto_truck_p2p t where t.gmt_modified >= '2025-04-21 13:21:00' and t.gmt_modified < '2025-04-21 13:24:00' and deletionstatecode=0 ) t where t.flag=0" + jdbcLineages = SQLUtils.parseLineage(sql) + assert("rt_zto_truck_p2p".equals(jdbcLineages.map(_._1).mkString(",")), "子查询select语句解析异常") + + //常规join + sql = "select a.id,b.id from a left join b on a.id = b.id" + jdbcLineages = SQLUtils.parseLineage(sql) + assert("a,b".equals(jdbcLineages.map(_._1).mkString(",")), "基础join语句解析异常") + + //子查询join + sql = "select a.id,b.id from a left join (select * from b) bb on a.id = b.id" + jdbcLineages = SQLUtils.parseLineage(sql) + assert("a,b".equals(jdbcLineages.map(_._1).mkString(",")), "子查询join语句解析异常") + + //多层子查询 + sql = "select *from (select *from (select a.id from a) aa) aaa left join (select *from (select b.id from b) bb) bbb on aaa.id = bbb.id" + jdbcLineages = SQLUtils.parseLineage(sql) + assert("a,b".equals(jdbcLineages.map(_._1).mkString(",")), "多层子查询语句解析异常") + + //线上用例 + sql = "select batchNumber, unlaodTransferId, unloadCenterId, date_format(estimateDate , '%Y-%m-%d %h:%i:%s') estimateDate, date_format(actualEndDate , '%Y-%m-%d %h:%i:%s') actualEndDate, dispNum, dispWeight, transferInProNum, if(transferInProNum=0,0,transferInProWeight) as transferInProWeight, outProNum, outProWeight, publishDate from ( select t.batch_number as batchNumber, t.end_site_id as unlaodTransferId, t.end_center_id as unloadCenterId, case when estimate_end_date<='1999-01-01 00:00:00' then gps_arrive_date else estimate_end_date end as estimateDate , t.actual_end_date as actualEndDate, t.disp_bills + t.disp_bag_bills as dispNum, t.disp_weight as dispWeight, (t.in_pro_num - t.disp_bills - t.disp_bag_bills) as transferInProNum, t.in_pro_weight - t.disp_weight as transferInProWeight, if((t.disp_bills + t.disp_bag_bills)>0 and disp_weight=0,1,0) as flag, t.out_pro_num as outProNum, t.out_pro_weight as outProWeight, '2025-04-21 13:24:00' as publishDate from rt_zto_truck_p2p t where t.gmt_modified >= '2025-04-21 13:21:00' and t.gmt_modified < '2025-04-21 13:24:00' and deletionstatecode=0 ) t where t.flag=0" + jdbcLineages = SQLUtils.parseLineage(sql) + assert("rt_zto_truck_p2p".equals(jdbcLineages.map(_._1).mkString(",")), "线上用例解析异常") + + + } } -- Gitee