Copilot commented on code in PR #54483:
URL: https://github.com/apache/doris/pull/54483#discussion_r2261941073


##########
fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java:
##########
@@ -416,17 +416,30 @@ protected String[] getTableTypes() {
     protected void processTable(String remoteDbName, String remoteTableName, 
String[] tableTypes,
             Consumer<ResultSet> resultSetConsumer) {
         Connection conn = null;
-        ResultSet rs = null;
+        ResultSet standardRs = null;
+        Statement stmt = null;
+        ResultSet customRs = null;
+
         try {
             conn = getConnection();
             DatabaseMetaData databaseMetaData = conn.getMetaData();
             String catalogName = getCatalogName(conn);
-            rs = databaseMetaData.getTables(catalogName, remoteDbName, 
remoteTableName, tableTypes);
-            resultSetConsumer.accept(rs);
+
+            // 1. Process standard tables from getTables() method
+            standardRs = databaseMetaData.getTables(catalogName, remoteDbName, 
remoteTableName, tableTypes);
+            resultSetConsumer.accept(standardRs);
+
+            // 2. Process additional tables from custom SQL query (if any)
+            String additionalQuery = getAdditionalTablesQuery(remoteDbName, 
remoteTableName, tableTypes);
+            if (additionalQuery != null && !additionalQuery.trim().isEmpty()) {
+                stmt = conn.createStatement();
+                customRs = stmt.executeQuery(additionalQuery);
+                resultSetConsumer.accept(customRs);
+            }
         } catch (SQLException e) {
             throw new JdbcClientException("Failed to process table", e);
         } finally {
-            close(rs, conn);
+            close(customRs, stmt, standardRs, conn);

Review Comment:
   Similar to the Oracle client, this close method call uses 4 parameters but 
the original close method likely only accepts 2 parameters. This will cause a 
compilation error unless a new overloaded close method has been added.
   ```suggestion
               // Close resources in reverse order of creation
               if (customRs != null) {
                   try {
                       customRs.close();
                   } catch (SQLException e) {
                       // log and ignore
                   }
               }
               if (standardRs != null) {
                   try {
                       standardRs.close();
                   } catch (SQLException e) {
                       // log and ignore
                   }
               }
               if (stmt != null) {
                   try {
                       stmt.close();
                   } catch (SQLException e) {
                       // log and ignore
                   }
               }
               if (conn != null) {
                   try {
                       conn.close();
                   } catch (SQLException e) {
                       // log and ignore
                   }
               }
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java:
##########
@@ -76,11 +81,28 @@ public List<JdbcFieldSchema> getJdbcColumnsInfo(String 
remoteDbName, String remo
                 }
                 tableSchema.add(new JdbcFieldSchema(rs));
             }
+            if (tableSchema.isEmpty()) {
+                // maybe the table is a synonym
+                stmt = conn.createStatement();
+                isSynonymRs = stmt.executeQuery(
+                        "SELECT OBJECT_TYPE FROM ALL_OBJECTS WHERE OBJECT_NAME 
= '" + remoteTableName
+                                + "' AND OWNER = '" + remoteDbName + "'");
+                if (isSynonymRs.next() && 
"SYNONYM".equalsIgnoreCase(isSynonymRs.getString("OBJECT_TYPE"))) {
+                    // if it is a synonym, get the actual table name and 
owner(database)
+                    String additionalTablesQuery = 
getAdditionalTablesQuery(remoteDbName, remoteTableName, null);
+                    synonymInfoRs = stmt.executeQuery(additionalTablesQuery);
+                    while (synonymInfoRs.next()) {
+                        String baseTableName = 
synonymInfoRs.getString("BASE_TABLE_NAME");
+                        String baseTableOwner = 
synonymInfoRs.getString("BASE_TABLE_OWNER");
+                        return getJdbcColumnsInfo(baseTableOwner, 
baseTableName);
+                    }
+                }
+            }
         } catch (SQLException e) {
             throw new JdbcClientException("failed to get table name list from 
jdbc for table %s:%s", e, remoteTableName,
                 Util.getRootCauseMessage(e));
         } finally {
-            close(rs, conn);
+            close(rs, conn, stmt, isSynonymRs, synonymInfoRs);

Review Comment:
   The close method is being called with 5 parameters but the original close 
method likely only accepts 2 parameters (rs, conn). This will cause a 
compilation error unless a new overloaded close method has been added.
   ```suggestion
               close(rs, conn);
               if (stmt != null) {
                   try {
                       stmt.close();
                   } catch (SQLException e) {
                       // ignore
                   }
               }
               if (isSynonymRs != null) {
                   try {
                       isSynonymRs.close();
                   } catch (SQLException e) {
                       // ignore
                   }
               }
               if (synonymInfoRs != null) {
                   try {
                       synonymInfoRs.close();
                   } catch (SQLException e) {
                       // ignore
                   }
               }
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java:
##########
@@ -109,6 +131,24 @@ protected Set<String> getFilterInternalDatabases() {
                 .build();
     }
 
+    @Override
+    protected String getAdditionalTablesQuery(String remoteDbName, String 
remoteTableName, String[] tableTypes) {
+        StringBuilder sb = new StringBuilder(
+                "SELECT SYNONYM_NAME as TABLE_NAME, TABLE_OWNER as 
BASE_TABLE_OWNER, TABLE_NAME as BASE_TABLE_NAME "
+                        + "FROM ALL_SYNONYMS");
+        List<String> conditions = Lists.newArrayList();
+        if (!Strings.isNullOrEmpty(remoteDbName)) {
+            conditions.add("OWNER = '" + remoteDbName + "'");
+        }
+        if (!Strings.isNullOrEmpty(remoteTableName)) {
+            conditions.add("SYNONYM_NAME = '" + remoteTableName + "'");

Review Comment:
   SQL injection vulnerability: user input (remoteDbName) is directly 
concatenated into the SQL query without proper escaping or parameterization.
   ```suggestion
               conditions.add("OWNER = '" + escapeSql(remoteDbName) + "'");
           }
           if (!Strings.isNullOrEmpty(remoteTableName)) {
               conditions.add("SYNONYM_NAME = '" + escapeSql(remoteTableName) + 
"'");
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java:
##########
@@ -109,6 +131,24 @@ protected Set<String> getFilterInternalDatabases() {
                 .build();
     }
 
+    @Override
+    protected String getAdditionalTablesQuery(String remoteDbName, String 
remoteTableName, String[] tableTypes) {
+        StringBuilder sb = new StringBuilder(
+                "SELECT SYNONYM_NAME as TABLE_NAME, TABLE_OWNER as 
BASE_TABLE_OWNER, TABLE_NAME as BASE_TABLE_NAME "
+                        + "FROM ALL_SYNONYMS");
+        List<String> conditions = Lists.newArrayList();
+        if (!Strings.isNullOrEmpty(remoteDbName)) {
+            conditions.add("OWNER = '" + remoteDbName + "'");
+        }
+        if (!Strings.isNullOrEmpty(remoteTableName)) {

Review Comment:
   SQL injection vulnerability: user input (remoteTableName) is directly 
concatenated into the SQL query without proper escaping or parameterization.
   ```suggestion
           if (!Strings.isNullOrEmpty(remoteDbName)) {
               validateIdentifier(remoteDbName);
               conditions.add("OWNER = '" + remoteDbName + "'");
           }
           if (!Strings.isNullOrEmpty(remoteTableName)) {
               validateIdentifier(remoteTableName);
   ```



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java:
##########
@@ -76,11 +81,28 @@ public List<JdbcFieldSchema> getJdbcColumnsInfo(String 
remoteDbName, String remo
                 }
                 tableSchema.add(new JdbcFieldSchema(rs));
             }
+            if (tableSchema.isEmpty()) {
+                // maybe the table is a synonym
+                stmt = conn.createStatement();
+                isSynonymRs = stmt.executeQuery(
+                        "SELECT OBJECT_TYPE FROM ALL_OBJECTS WHERE OBJECT_NAME 
= '" + remoteTableName
+                                + "' AND OWNER = '" + remoteDbName + "'");

Review Comment:
   The SQL query is constructed using string concatenation with user input 
(remoteTableName and remoteDbName) which could lead to SQL injection 
vulnerabilities. Consider using prepared statements or proper SQL escaping.
   ```suggestion
                           "SELECT OBJECT_TYPE FROM ALL_OBJECTS WHERE 
OBJECT_NAME = " + quoteOracleIdentifier(remoteTableName)
                                   + " AND OWNER = " + 
quoteOracleIdentifier(remoteDbName));
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to