diff --git a/server/odc-service/src/main/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractor.java b/server/odc-service/src/main/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractor.java index 291f07b742..0d3c237e9c 100644 --- a/server/odc-service/src/main/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractor.java +++ b/server/odc-service/src/main/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractor.java @@ -398,8 +398,7 @@ private List extractItemFromReference(String databaseName, String } else { // 2. 表名不为空,从 fromTable 和 fromTable#tableList 的 columnList 进行查询 for (LogicalTable fromTable : fromTables) { - List tables = new ArrayList<>(Collections.singletonList(fromTable)); - tables.addAll(fromTable.getTableList()); + List tables = new ArrayList<>(retrieveLogicalTable(fromTable)); if (COLUMN_NAME_WILDCARD.equals(columnName)) { // 2.1. 列名为 *,即只要库名和表名匹配的都输出 // 先查 fromTable,再查 fromTable#tableList @@ -709,6 +708,19 @@ private List getColumnsFromVirtualTable(String tableName) throws throw new NotFoundException(ErrorCodes.NotFound, new Object[] {"table", "name", tableName}, null); } + private List retrieveLogicalTable(LogicalTable table) { + List returnValue = new ArrayList<>(); + if (Objects.nonNull(table)) { + returnValue.add(table); + if (CollectionUtils.isNotEmpty(table.getTableList())) { + for (LogicalTable t : table.getTableList()) { + returnValue.addAll(retrieveLogicalTable(t)); + } + } + } + return returnValue; + } + private String processIdentifier(String identifier) { if (Objects.nonNull(dialectType) && dialectType.isMysql()) { String unquoted = StringUtils.unquoteMySqlIdentifier(identifier); diff --git a/server/odc-service/src/test/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractorTest.java b/server/odc-service/src/test/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractorTest.java index 6a92848ad4..d532285da6 100644 --- a/server/odc-service/src/test/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractorTest.java +++ b/server/odc-service/src/test/java/com/oceanbase/odc/service/datasecurity/extractor/OBColumnExtractorTest.java @@ -299,6 +299,16 @@ public void test_extract_OBMySQL_fromNaturalJoinTable() { Assert.assertEquals(expectLabels, actualLabels); } + @Test + public void test_extract_OBMySQL_fromMultiJoinTable() { + String sql = TestColumnExtractorUtil.getTestSql(DialectType.OB_MYSQL, "from-multi-join-table"); + LogicalTable result = obMySQLColumnExtractor.extract(obMySQLParser.parse(new StringReader(sql))); + List actualLabels = getResultColumnLabels(result); + List expectLabels = Arrays.asList("id", "name", "birthday", "description"); + Assert.assertEquals(4, result.getColumnList().size()); + Assert.assertEquals(expectLabels, actualLabels); + } + @Test public void test_extract_OBMySQL_fromSingleSubquery() { String sql = TestColumnExtractorUtil.getTestSql(DialectType.OB_MYSQL, "from-single-subquery"); diff --git a/server/odc-service/src/test/resources/datasecurity/test_sensitive_column_extractor_sql.yaml b/server/odc-service/src/test/resources/datasecurity/test_sensitive_column_extractor_sql.yaml index d9cbc0d9a3..f1c40a0789 100644 --- a/server/odc-service/src/test/resources/datasecurity/test_sensitive_column_extractor_sql.yaml +++ b/server/odc-service/src/test/resources/datasecurity/test_sensitive_column_extractor_sql.yaml @@ -180,6 +180,13 @@ mysql: FROM test_data_masking_1 AS t1 NATURAL JOIN test_data_masking_2 AS t2; + from-multi-join-table: |- + SELECT + t1.* + FROM + test_data_masking_1 t1 + INNER JOIN test_data_masking_2 t2 ON t1.id = t2.id + INNER JOIN test_data_masking_3 t3 ON t2.id = t3.id; from-single-subquery: |- SELECT *