fix(mysql): preserve results after hash comments

This commit is contained in:
zipg
2026-07-19 08:53:20 +08:00
committed by GitHub
parent a0410c5834
commit d14fd84709
+18 -6
View File
@@ -13,7 +13,7 @@ use std::time::Instant;
use tokio_util::sync::CancellationToken;
use crate::models::connection::{ConnectionConfig, DatabaseConnectionInfo, DatabaseType};
use crate::sql::starts_with_executable_sql_keyword;
use crate::sql::{starts_with_executable_sql_keyword, starts_with_executable_sql_keyword_for_database};
use crate::types::{
ColumnInfo, CompletionAssistantCandidate, CompletionAssistantCandidateKind, CompletionAssistantMatchMode,
CompletionAssistantObjectKind, CompletionAssistantRequest, CompletionAssistantResponse, DatabaseInfo,
@@ -3198,8 +3198,11 @@ fn prefers_text_protocol_query(sql: &str, dialect: MySqlQueryDialect) -> bool {
}
fn is_result_set_query(sql: &str, dialect: MySqlQueryDialect) -> bool {
starts_with_executable_sql_keyword(sql, &["SELECT", "SHOW", "DESCRIBE", "EXPLAIN", "WITH", "CALL"])
|| dialect.supports_admin_show_results && is_admin_show_query(sql)
starts_with_executable_sql_keyword_for_database(
sql,
&["SELECT", "SHOW", "DESCRIBE", "EXPLAIN", "WITH", "CALL"],
DatabaseType::Mysql,
) || dialect.supports_admin_show_results && is_admin_show_query(sql)
}
fn requires_text_protocol_query(sql: &str, dialect: MySqlQueryDialect) -> bool {
@@ -3207,12 +3210,11 @@ fn requires_text_protocol_query(sql: &str, dialect: MySqlQueryDialect) -> bool {
return true;
}
if !starts_with_executable_sql_keyword(sql, &["SHOW"]) {
if !starts_with_executable_sql_keyword_for_database(sql, &["SHOW"], DatabaseType::Mysql) {
return false;
}
let tokens =
sql.trim().trim_end_matches(';').split_whitespace().map(|token| token.to_ascii_lowercase()).collect::<Vec<_>>();
let tokens = leading_sql_word_tokens(sql, 3);
if tokens.len() >= 2 && tokens[0] == "show" && tokens[1] == "grants" {
return true;
}
@@ -3987,6 +3989,16 @@ mod tests {
assert!(is_result_set_query(sql, MySqlQueryDialect::default()));
}
#[test]
fn mysql_hash_comments_before_queries_preserve_result_sets_per_issue_3830() {
let dialect = MySqlQueryDialect::default();
assert!(is_result_set_query("# 注释\nSELECT NOW()", dialect));
assert!(prefers_text_protocol_query("# 注释\nSELECT NOW()", dialect));
assert!(requires_text_protocol_query("# inspect sessions\nSHOW PROCESSLIST", dialect));
assert!(!is_result_set_query("# update row\nUPDATE users SET name = 'Ada' WHERE id = 1", dialect));
}
#[test]
fn mysql_desc_queries_are_treated_as_result_sets() {
assert!(is_result_set_query("DESC users", MySqlQueryDialect::default()));