From a32ead56b97d172767bf8b4b969d9e78cfbd00f3 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Mon, 15 Jun 2026 14:18:40 +0800 Subject: [PATCH] fix(query): skip comment-only SQL execution --- crates/dbx-core/src/query.rs | 26 ++++++++++++++++++++++++++ crates/dbx-core/src/sql.rs | 15 ++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/crates/dbx-core/src/query.rs b/crates/dbx-core/src/query.rs index 12fd419c6..86b5c03c5 100644 --- a/crates/dbx-core/src/query.rs +++ b/crates/dbx-core/src/query.rs @@ -968,6 +968,15 @@ pub async fn execute_sql_statement_with_options( return Err("Use MongoDB-specific commands".to_string()); } + let db_type = connection_database_type(state, connection_id).await; + let has_executable_sql = db_type.map_or_else( + || crate::sql::has_executable_sql(sql), + |db_type| crate::sql::has_executable_sql_for_database(sql, db_type), + ); + if !has_executable_sql { + return Ok(empty_query_result(0)); + } + // When a query tab has a client session, keep even database-less execution // on that tab-scoped pool so connection-level state (for example MySQL @vars) // survives across runs. @@ -1094,6 +1103,9 @@ pub async fn execute_multi_core_with_options( || split_sql_statements(sql), |db_type| crate::sql::split_sql_statements_for_database(sql, db_type), ); + if statements.is_empty() { + return Ok(vec![empty_query_result(0)]); + } let mysql_pool = { let connections = state.connections.read().await; @@ -1204,6 +1216,20 @@ fn error_query_result(message: String) -> db::QueryResult { } } +fn empty_query_result(execution_time_ms: u128) -> db::QueryResult { + db::QueryResult { + columns: vec![], + column_types: Vec::new(), + column_sortables: vec![], + rows: vec![], + affected_rows: 0, + execution_time_ms, + truncated: false, + session_id: None, + has_more: false, + } +} + async fn execute_multi_sqlserver( state: &AppState, pool_key: &str, diff --git a/crates/dbx-core/src/sql.rs b/crates/dbx-core/src/sql.rs index 62753ac9e..a430e8cd3 100644 --- a/crates/dbx-core/src/sql.rs +++ b/crates/dbx-core/src/sql.rs @@ -1585,10 +1585,14 @@ fn dollar_quote_tag_at(chars: &[char], start: usize) -> Option { None } -fn has_executable_sql(statement: &str) -> bool { +pub fn has_executable_sql(statement: &str) -> bool { has_executable_sql_with_options(statement, SqlParsingOptions::default()) } +pub fn has_executable_sql_for_database(statement: &str, db_type: DatabaseType) -> bool { + has_executable_sql_with_options(statement, SqlParsingOptions::for_database_type(db_type)) +} + fn executable_sql_bounds(statement: &str, options: SqlParsingOptions) -> Option<(usize, usize)> { let trimmed_end = statement.trim_end().len(); let trimmed = &statement[..trimmed_end]; @@ -1771,6 +1775,15 @@ mod tests { ); } + #[test] + fn skips_comment_only_statement_with_semicolon() { + assert_eq!( + split_sql_script("-- insert sqluser.tb_a values (6,'006','测试6','无');").unwrap(), + Vec::::new() + ); + assert!(!super::has_executable_sql("-- insert sqluser.tb_a values (6,'006','测试6','无');")); + } + #[test] fn keeps_postgres_dollar_quoted_function_body_together() { let sql = "\