From 9f627b57cf1fd90741addc95e5fcdfdbd39deb0b Mon Sep 17 00:00:00 2001 From: LimJiaWenBrenda Date: Mon, 20 Apr 2026 14:50:09 +0800 Subject: [PATCH 1/4] Changed db to required for tsfile and csv file type + Checked db in param and sql for sql file type --- .../apache/iotdb/tool/common/OptionsUtil.java | 32 +++++++++++++++---- .../iotdb/tool/data/ImportDataTable.java | 19 +++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java index d128a01bcc86d..b60809eba636a 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java @@ -157,13 +157,7 @@ public static Options createTreeImportCommonOptions() { } public static Options createTableImportCommonOptions() { - Options options = createImportCommonOptions(); - - Option opDatabase = - Option.builder(DB_ARGS).longOpt(DB_NAME).argName(DB_ARGS).hasArg().desc(DB_DESC).build(); - options.addOption(opDatabase); - - return options; + return createImportCommonOptions(); } public static Options createExportCommonOptions() { @@ -731,6 +725,16 @@ public static Options createImportTsFileOptions() { public static Options createTableImportCsvOptions() { Options options = createTableImportCommonOptions(); + Option opDatabase = + Option.builder(DB_ARGS) + .longOpt(DB_NAME) + .argName(DB_ARGS) + .required() + .hasArg() + .desc(DB_DESC) + .build(); + options.addOption(opDatabase); + Option opTable = Option.builder(TABLE_ARGS) .longOpt(TABLE_ARGS) @@ -830,6 +834,10 @@ public static Options createTableImportCsvOptions() { public static Options createTableImportSqlOptions() { Options options = createTableImportCommonOptions(); + Option opDatabase = + Option.builder(DB_ARGS).longOpt(DB_NAME).argName(DB_ARGS).hasArg().desc(DB_DESC).build(); + options.addOption(opDatabase); + Option opFile = Option.builder(FILE_ARGS) .required() @@ -889,6 +897,16 @@ public static Options createTableImportSqlOptions() { public static Options createTableImportTsFileOptions() { Options options = createTableImportCommonOptions(); + Option opDatabase = + Option.builder(DB_ARGS) + .longOpt(DB_NAME) + .argName(DB_ARGS) + .required() + .hasArg() + .desc(DB_DESC) + .build(); + options.addOption(opDatabase); + Option opFile = Option.builder(FILE_ARGS) .required() diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java index f6e84362d90d7..2420334f3af38 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java @@ -160,6 +160,16 @@ protected static void processSuccessFile() { loadFileSuccessfulNum.increment(); } + private static String extractDbFromSql(String sql) { + String regex = "into\\s+(?:\"([^\"]+)\"|(\\w+))\\.(?:\"([^\"]+)\"|(\\w+))"; + Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(sql); + if (matcher.find()) { + return matcher.group(1) != null ? matcher.group(1) : matcher.group(2); + } + return null; + } + @SuppressWarnings("java:S2259") protected void importFromSqlFile(File file) { ArrayList> failedRecords = new ArrayList<>(); @@ -174,6 +184,15 @@ protected void importFromSqlFile(File file) { while ((sql = br.readLine()) != null) { try (ITableSession session = sessionPool.getSession()) { sql = sql.replace(";", ""); + String dbName = extractDbFromSql(sql); + if (dbName != null && !dbName.equalsIgnoreCase(database)) { + ioTPrinter.println( + String.format( + "The database in SQL statement '%s' does not match the target database '%s'", + dbName, database)); + failedRecords.add(Collections.singletonList(sql)); + continue; + } session.executeNonQueryStatement(sql); } catch (IoTDBConnectionException | StatementExecutionException e) { ioTPrinter.println(e.getMessage()); From 2b5fd65f87fe13b9c255142c7bd1bc6b9b494319 Mon Sep 17 00:00:00 2001 From: LimJiaWenBrenda Date: Mon, 20 Apr 2026 15:15:29 +0800 Subject: [PATCH 2/4] Skipped checking if db parameter is not used for sql file type --- .../main/java/org/apache/iotdb/tool/data/ImportDataTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java index 2420334f3af38..b6142f1a723a6 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java @@ -185,7 +185,7 @@ protected void importFromSqlFile(File file) { try (ITableSession session = sessionPool.getSession()) { sql = sql.replace(";", ""); String dbName = extractDbFromSql(sql); - if (dbName != null && !dbName.equalsIgnoreCase(database)) { + if (database != null && dbName != null && !dbName.equalsIgnoreCase(database)) { ioTPrinter.println( String.format( "The database in SQL statement '%s' does not match the target database '%s'", From 4c50cc35e2c3962b79c19316432eaa2f2e1dd813 Mon Sep 17 00:00:00 2001 From: LimJiaWenBrenda Date: Mon, 20 Apr 2026 16:48:31 +0800 Subject: [PATCH 3/4] Enhanced regex expression to cover more scenario --- .../apache/iotdb/tool/data/ImportDataTable.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java index b6142f1a723a6..32a4ae8ffceb4 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java @@ -161,11 +161,18 @@ protected static void processSuccessFile() { } private static String extractDbFromSql(String sql) { - String regex = "into\\s+(?:\"([^\"]+)\"|(\\w+))\\.(?:\"([^\"]+)\"|(\\w+))"; + // group N: 双引号标识符 (""转义) + // group N+1: 反引号标识符 (``转义) + // group N+2: 普通标识符 + String id = "(?:\"((?:[^\"]|\"\")*)\"" + "|`((?:[^`]|``)*)`" + "|(\\w+))"; + String regex = "into\\s+" + id + "\\s*\\.\\s*" + id; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(sql); if (matcher.find()) { - return matcher.group(1) != null ? matcher.group(1) : matcher.group(2); + // db name: group 1 (双引号), group 2 (反引号), group 3 (普通) + if (matcher.group(1) != null) return matcher.group(1).replace("\"\"", "\""); + if (matcher.group(2) != null) return matcher.group(2).replace("``", "`"); + return matcher.group(3); } return null; } @@ -183,7 +190,10 @@ protected void importFromSqlFile(File file) { String sql; while ((sql = br.readLine()) != null) { try (ITableSession session = sessionPool.getSession()) { - sql = sql.replace(";", ""); + sql = sql.trim(); + if (sql.endsWith(";")) { + sql = sql.substring(0, sql.length() - 1); + } String dbName = extractDbFromSql(sql); if (database != null && dbName != null && !dbName.equalsIgnoreCase(database)) { ioTPrinter.println( From 14959045bb7c58e02239619ccd40124492b88189 Mon Sep 17 00:00:00 2001 From: LimJiaWenBrenda Date: Mon, 20 Apr 2026 17:18:10 +0800 Subject: [PATCH 4/4] Fixed copilot review suggestion --- .../iotdb/tool/data/ImportDataTable.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java index 32a4ae8ffceb4..506da8b8e17ce 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java @@ -65,6 +65,17 @@ public class ImportDataTable extends AbstractImportData { private static Map dataTypes = new HashMap<>(); private static Map columnCategory = new HashMap<>(); + private static final Pattern DB_FROM_SQL_PATTERN; + + static { + // group N: 双引号标识符 (""转义) + // group N+1: 反引号标识符 (``转义) + // group N+2: 普通标识符 + String id = "(?:\"((?:[^\"]|\"\")*)\"" + "|`((?:[^`]|``)*)`" + "|(\\w+))"; + DB_FROM_SQL_PATTERN = + Pattern.compile("into\\s+" + id + "\\s*\\.\\s*" + id, Pattern.CASE_INSENSITIVE); + } + public void init() throws InterruptedException { TableSessionPoolBuilder tableSessionPoolBuilder = new TableSessionPoolBuilder() @@ -161,13 +172,8 @@ protected static void processSuccessFile() { } private static String extractDbFromSql(String sql) { - // group N: 双引号标识符 (""转义) - // group N+1: 反引号标识符 (``转义) - // group N+2: 普通标识符 - String id = "(?:\"((?:[^\"]|\"\")*)\"" + "|`((?:[^`]|``)*)`" + "|(\\w+))"; - String regex = "into\\s+" + id + "\\s*\\.\\s*" + id; - Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(sql); + + Matcher matcher = DB_FROM_SQL_PATTERN.matcher(sql); if (matcher.find()) { // db name: group 1 (双引号), group 2 (反引号), group 3 (普通) if (matcher.group(1) != null) return matcher.group(1).replace("\"\"", "\""); @@ -198,7 +204,7 @@ protected void importFromSqlFile(File file) { if (database != null && dbName != null && !dbName.equalsIgnoreCase(database)) { ioTPrinter.println( String.format( - "The database in SQL statement '%s' does not match the target database '%s'", + "The extracted database '%s' in SQL statement does not match the target database '%s'", dbName, database)); failedRecords.add(Collections.singletonList(sql)); continue;