Skip to content

Commit c975264

Browse files
committed
fix(sql_editor): 修正游标位置时获取正确的SQL语句
- 优化 sql_text_for_run_current 函数,避免空语句返回 None - 使用解析后语句列表,根据游标前语句数量准确索引当前语句 - 添加单元测试验证多行语句中游标内语句提取正确性 - 确保游标落在语句内部时返回完整的多行SQL片段
1 parent cdb99b9 commit c975264

1 file changed

Lines changed: 22 additions & 8 deletions

File tree

‎crates/db_view/src/sql_editor_view.rs‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ fn current_sql_statement(
147147
) -> Option<String> {
148148
let cursor_offset = clamp_to_char_boundary(editor_text, cursor_offset);
149149
let (prefix, suffix) = editor_text.split_at(cursor_offset);
150+
let statements = parse_sql_statements(editor_text, database_type.clone());
151+
if statements.is_empty() {
152+
return None;
153+
}
150154
if cursor_starts_next_statement(prefix, suffix) {
151155
if let Some(statement) = parse_sql_statements(suffix, database_type.clone())
152156
.into_iter()
@@ -155,14 +159,12 @@ fn current_sql_statement(
155159
return Some(statement);
156160
}
157161
}
158-
parse_sql_statements(prefix, database_type.clone())
159-
.into_iter()
160-
.last()
161-
.or_else(|| {
162-
parse_sql_statements(editor_text, database_type)
163-
.into_iter()
164-
.next()
165-
})
162+
let prefix_statement_count = parse_sql_statements(prefix, database_type).len();
163+
let statement_index = prefix_statement_count.saturating_sub(1);
164+
165+
statements
166+
.get(statement_index.min(statements.len() - 1))
167+
.cloned()
166168
}
167169

168170
fn parse_sql_statements(sql: &str, database_type: DatabaseType) -> Vec<String> {
@@ -1962,6 +1964,18 @@ mod tests {
19621964
assert_eq!("select * from orders", actual);
19631965
}
19641966

1967+
#[test]
1968+
fn run_query_text_uses_full_multiline_statement_when_cursor_is_inside() {
1969+
let sql = "select * from users;\nselect id,\n name\nfrom orders\nwhere active = 1;\nselect * from products;";
1970+
let cursor_offset = sql.find("name").expect("statement exists") + "na".len();
1971+
let actual = sql_text_for_run_current(sql, "", cursor_offset, DatabaseType::MySQL);
1972+
1973+
assert_eq!(
1974+
"select id,\n name\nfrom orders\nwhere active = 1",
1975+
actual
1976+
);
1977+
}
1978+
19651979
#[test]
19661980
fn run_query_text_ignores_semicolon_inside_string() {
19671981
let sql = "select 1;\nselect ';not delimiter' as value;\nselect 3;";

0 commit comments

Comments
 (0)