sql_lsp/dialects/
mysql.rs

1use crate::dialect::Dialect;
2use crate::parser::SqlParser;
3use crate::schema::Schema;
4use async_trait::async_trait;
5use tower_lsp::lsp_types::{
6    CompletionItem, CompletionItemKind, Diagnostic, Hover, Location, Position,
7};
8
9pub struct MysqlDialect {
10    parser: std::sync::Mutex<SqlParser>,
11}
12
13impl Default for MysqlDialect {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl MysqlDialect {
20    pub fn new() -> Self {
21        Self {
22            parser: std::sync::Mutex::new(SqlParser::new()),
23        }
24    }
25
26    /// 创建关键字补全项
27    fn create_keyword_item(&self, keyword: &str) -> CompletionItem {
28        CompletionItem {
29            label: keyword.to_string(),
30            kind: Some(CompletionItemKind::KEYWORD),
31            detail: Some(format!("MySQL keyword: {}", keyword)),
32            documentation: None,
33            deprecated: None,
34            preselect: None,
35            sort_text: Some(format!("0{}", keyword)),
36            filter_text: None,
37            insert_text: Some(keyword.to_string()),
38            insert_text_format: None,
39            insert_text_mode: None,
40            text_edit: None,
41            additional_text_edits: None,
42            commit_characters: None,
43            command: None,
44            data: None,
45            tags: None,
46            label_details: None,
47        }
48    }
49
50    /// 创建表补全项
51    fn create_table_item(&self, table: &crate::schema::Table) -> CompletionItem {
52        CompletionItem {
53            label: table.name.clone(),
54            kind: Some(CompletionItemKind::CLASS),
55            detail: Some(format!("Table: {}", table.name)),
56            documentation: table
57                .comment
58                .clone()
59                .map(tower_lsp::lsp_types::Documentation::String),
60            deprecated: None,
61            preselect: None,
62            sort_text: Some(format!("1{}", table.name)),
63            filter_text: None,
64            insert_text: Some(table.name.clone()),
65            insert_text_format: None,
66            insert_text_mode: None,
67            text_edit: None,
68            additional_text_edits: None,
69            commit_characters: None,
70            command: None,
71            data: None,
72            tags: None,
73            label_details: None,
74        }
75    }
76
77    /// 创建列补全项
78    fn create_column_item(
79        &self,
80        column: &crate::schema::Column,
81        table_name: Option<&str>,
82    ) -> CompletionItem {
83        let label = if let Some(table) = table_name {
84            format!("{}.{}", table, column.name)
85        } else {
86            column.name.clone()
87        };
88
89        let detail = if let Some(table) = table_name {
90            format!("Column: {}.{} ({})", table, column.name, column.data_type)
91        } else {
92            format!("Column: {} ({})", column.name, column.data_type)
93        };
94
95        CompletionItem {
96            label,
97            kind: Some(CompletionItemKind::FIELD),
98            detail: Some(detail),
99            documentation: column
100                .comment
101                .clone()
102                .map(tower_lsp::lsp_types::Documentation::String),
103            deprecated: None,
104            preselect: None,
105            sort_text: Some(format!("2{}", column.name)),
106            filter_text: None,
107            insert_text: Some(column.name.clone()),
108            insert_text_format: None,
109            insert_text_mode: None,
110            text_edit: None,
111            additional_text_edits: None,
112            commit_characters: None,
113            command: None,
114            data: None,
115            tags: None,
116            label_details: None,
117        }
118    }
119}
120
121#[async_trait]
122impl Dialect for MysqlDialect {
123    fn name(&self) -> &str {
124        "mysql"
125    }
126
127    async fn parse(&self, sql: &str, _schema: Option<&Schema>) -> Vec<Diagnostic> {
128        // 使用 Tree-sitter 进行容错 SQL 解析
129        let mut parser = self.parser.lock().unwrap();
130        let parse_result = parser.parse(sql);
131        parse_result.diagnostics
132    }
133
134    async fn completion(
135        &self,
136        sql: &str,
137        position: Position,
138        schema: Option<&Schema>,
139    ) -> Vec<CompletionItem> {
140        let mut parser = self.parser.lock().unwrap();
141        let parse_result = parser.parse(sql);
142
143        // 分析补全上下文
144        let context = if let Some(tree) = &parse_result.tree {
145            if let Some(node) = parser.get_node_at_position(tree, position) {
146                parser.analyze_completion_context(node, sql, position)
147            } else {
148                crate::parser::CompletionContext::Default
149            }
150        } else {
151            crate::parser::CompletionContext::Default
152        };
153
154        let mut items = Vec::new();
155
156        // 根据上下文提供不同的补全
157        match context {
158            crate::parser::CompletionContext::FromClause
159            | crate::parser::CompletionContext::JoinClause => {
160                // FROM/JOIN 子句:只补全表名,不要关键字
161                // 添加表名补全
162                if let Some(schema) = schema {
163                    for table in &schema.tables {
164                        items.push(self.create_table_item(table));
165                    }
166                }
167            }
168
169            crate::parser::CompletionContext::SelectClause => {
170                // SELECT 子句:优先补全列名,然后是 SELECT 相关关键字
171                // Extract prefix from cursor position
172                let prefix = {
173                    let lines: Vec<&str> = sql.lines().collect();
174                    let line_text = lines.get(position.line as usize).unwrap_or(&"");
175                    let text_before =
176                        &line_text[..position.character.min(line_text.len() as u32) as usize];
177
178                    // Extract last word/identifier before cursor
179                    text_before
180                        .split(|c: char| c.is_whitespace() || c == ',' || c == '(')
181                        .next_back()
182                        .unwrap_or("")
183                        .to_lowercase()
184                };
185
186                // 先添加列名补全(优先级更高)
187                if let Some(schema) = schema {
188                    // Check if query has multiple tables (to decide whether to use table prefix)
189                    let use_table_prefix = if let Some(tree) = &parse_result.tree {
190                        let referenced_tables = parser.extract_referenced_tables(tree, sql);
191                        referenced_tables.len() > 1
192                    } else {
193                        false
194                    };
195
196                    for table in &schema.tables {
197                        for column in &table.columns {
198                            // 单表查询时不使用表名前缀,多表查询时使用前缀避免歧义
199                            let table_name = if use_table_prefix {
200                                Some(table.name.as_str())
201                            } else {
202                                None
203                            };
204                            let mut item = self.create_column_item(column, table_name);
205
206                            // Smart sorting based on prefix match
207                            if !prefix.is_empty() && column.name.to_lowercase().starts_with(&prefix)
208                            {
209                                // Prefix match: highest priority
210                                item.sort_text = Some(format!("00{}", column.name));
211                            } else {
212                                // No match: normal column priority
213                                item.sort_text = Some(format!("01{}", column.name));
214                            }
215
216                            items.push(item);
217                        }
218                    }
219                }
220
221                // 然后添加 SELECT 相关关键字(优先级较低)
222                let select_keywords = vec!["SELECT", "DISTINCT", "AS", "FROM"];
223                for keyword in select_keywords {
224                    let mut item = self.create_keyword_item(keyword);
225                    item.sort_text = Some(format!("1{}", keyword));
226                    items.push(item);
227                }
228            }
229
230            crate::parser::CompletionContext::WhereClause => {
231                // WHERE 子句:优先补全列名,然后是操作符,不要关键字
232                // 先添加列名 (优先级更高)
233                if let Some(schema) = schema {
234                    if let Some(tree) = &parse_result.tree {
235                        let referenced_tables = parser.extract_referenced_tables(tree, sql);
236                        let aliases = parser.extract_aliases(tree, sql);
237
238                        // Resolve aliases to real table names
239                        let mut real_table_names: Vec<String> = referenced_tables
240                            .iter()
241                            .map(|t| aliases.get(t).unwrap_or(t).clone())
242                            .collect();
243                        real_table_names.dedup();
244
245                        // 单表查询时不使用表名前缀,多表查询时使用前缀避免歧义
246                        let use_table_prefix = real_table_names.len() > 1;
247
248                        for table in &schema.tables {
249                            if real_table_names.contains(&table.name) {
250                                for column in &table.columns {
251                                    let table_name = if use_table_prefix {
252                                        Some(table.name.as_str())
253                                    } else {
254                                        None
255                                    };
256                                    let mut item = self.create_column_item(column, table_name);
257                                    item.sort_text = Some(format!("0{}", column.name)); // Columns first
258                                    items.push(item);
259                                }
260                            }
261                        }
262                    }
263                }
264
265                // 然后添加操作符 (优先级较低)
266                // 只添加关键字形式的运算符,不添加符号运算符
267                let operators = vec!["LIKE", "IN", "BETWEEN", "IS NULL", "IS NOT NULL"];
268                for op in operators {
269                    items.push(CompletionItem {
270                        label: op.to_string(),
271                        kind: Some(CompletionItemKind::OPERATOR),
272                        detail: Some(format!("Operator: {}", op)),
273                        documentation: None,
274                        deprecated: None,
275                        preselect: None,
276                        sort_text: Some(format!("1{}", op)), // Operators after columns
277                        filter_text: None,
278                        insert_text: Some(op.to_string()),
279                        insert_text_format: None,
280                        insert_text_mode: None,
281                        text_edit: None,
282                        additional_text_edits: None,
283                        commit_characters: None,
284                        command: None,
285                        data: None,
286                        tags: None,
287                        label_details: None,
288                    });
289                }
290            }
291
292            crate::parser::CompletionContext::OrderByClause => {
293                // ORDER BY:补全列名和排序关键字
294                // 添加列名补全 (优先级高)
295                if let Some(schema) = schema {
296                    // Check if query has multiple tables (to decide whether to use table prefix)
297                    if let Some(tree) = &parse_result.tree {
298                        let referenced_tables = parser.extract_referenced_tables(tree, sql);
299                        let aliases = parser.extract_aliases(tree, sql);
300
301                        // Resolve aliases to real table names
302                        let mut real_table_names: Vec<String> = referenced_tables
303                            .iter()
304                            .map(|t| aliases.get(t).unwrap_or(t).clone())
305                            .collect();
306                        real_table_names.dedup();
307
308                        // 单表查询时不使用表名前缀,多表查询时使用前缀避免歧义
309                        let use_table_prefix = real_table_names.len() > 1;
310
311                        for table in &schema.tables {
312                            // 只添加查询中引用的表的列
313                            if real_table_names.is_empty() || real_table_names.contains(&table.name)
314                            {
315                                for column in &table.columns {
316                                    let table_name = if use_table_prefix {
317                                        Some(table.name.as_str())
318                                    } else {
319                                        None
320                                    };
321                                    let mut item = self.create_column_item(column, table_name);
322                                    item.sort_text = Some(format!("0{}", column.name)); // Columns first
323                                    items.push(item);
324                                }
325                            }
326                        }
327                    } else {
328                        // 如果没有解析树,默认返回所有列,不带前缀
329                        for table in &schema.tables {
330                            for column in &table.columns {
331                                let mut item = self.create_column_item(column, None);
332                                item.sort_text = Some(format!("0{}", column.name)); // Columns first
333                                items.push(item);
334                            }
335                        }
336                    }
337                }
338
339                // 添加 ORDER BY 排序关键字 (优先级低)
340                let keywords = vec!["ASC", "DESC"];
341                for keyword in keywords {
342                    let mut item = self.create_keyword_item(keyword);
343                    item.sort_text = Some(format!("1{}", keyword)); // Keywords after columns
344                    items.push(item);
345                }
346            }
347
348            crate::parser::CompletionContext::GroupByClause => {
349                // GROUP BY:只补全列名,不需要排序关键字
350                // 添加列名补全
351                if let Some(schema) = schema {
352                    // Check if query has multiple tables (to decide whether to use table prefix)
353                    if let Some(tree) = &parse_result.tree {
354                        let referenced_tables = parser.extract_referenced_tables(tree, sql);
355                        let aliases = parser.extract_aliases(tree, sql);
356
357                        // Resolve aliases to real table names
358                        let mut real_table_names: Vec<String> = referenced_tables
359                            .iter()
360                            .map(|t| aliases.get(t).unwrap_or(t).clone())
361                            .collect();
362                        real_table_names.dedup();
363
364                        // 单表查询时不使用表名前缀,多表查询时使用前缀避免歧义
365                        let use_table_prefix = real_table_names.len() > 1;
366
367                        for table in &schema.tables {
368                            // 只添加查询中引用的表的列
369                            if real_table_names.is_empty() || real_table_names.contains(&table.name)
370                            {
371                                for column in &table.columns {
372                                    let table_name = if use_table_prefix {
373                                        Some(table.name.as_str())
374                                    } else {
375                                        None
376                                    };
377                                    let mut item = self.create_column_item(column, table_name);
378                                    item.sort_text = Some(format!("0{}", column.name)); // Columns first
379                                    items.push(item);
380                                }
381                            }
382                        }
383                    } else {
384                        // 如果没有解析树,默认返回所有列,不带前缀
385                        for table in &schema.tables {
386                            for column in &table.columns {
387                                let mut item = self.create_column_item(column, None);
388                                item.sort_text = Some(format!("0{}", column.name)); // Columns first
389                                items.push(item);
390                            }
391                        }
392                    }
393                }
394                // GROUP BY 不添加任何关键字
395            }
396
397            crate::parser::CompletionContext::HavingClause => {
398                // HAVING 子句:列名(优先) > 聚合函数 > 操作符 > 关键字
399
400                // 1. 添加列名补全 (优先级最高 "0")
401                if let Some(schema) = schema {
402                    // Check if query has multiple tables (to decide whether to use table prefix)
403                    // Same logic as WHERE/ORDER BY
404                    if let Some(tree) = &parse_result.tree {
405                        let referenced_tables = parser.extract_referenced_tables(tree, sql);
406                        let aliases = parser.extract_aliases(tree, sql);
407                        let mut real_table_names: Vec<String> = referenced_tables
408                            .iter()
409                            .map(|t| aliases.get(t).unwrap_or(t).clone())
410                            .collect();
411                        real_table_names.dedup();
412                        let use_table_prefix = real_table_names.len() > 1;
413
414                        for table in &schema.tables {
415                            if real_table_names.is_empty() || real_table_names.contains(&table.name)
416                            {
417                                for column in &table.columns {
418                                    let table_name = if use_table_prefix {
419                                        Some(table.name.as_str())
420                                    } else {
421                                        None
422                                    };
423                                    let mut item = self.create_column_item(column, table_name);
424                                    item.sort_text = Some(format!("0{}", column.name));
425                                    items.push(item);
426                                }
427                            }
428                        }
429                    }
430                }
431
432                // 2. 添加聚合函数 (优先级中 "1")
433                let aggregate_functions = vec!["COUNT", "SUM", "AVG", "MIN", "MAX"];
434                for func in aggregate_functions {
435                    let mut item = self.create_keyword_item(func);
436                    item.kind = Some(CompletionItemKind::FUNCTION);
437                    item.sort_text = Some(format!("1{}", func));
438                    items.push(item);
439                }
440
441                // 3. 添加逻辑关键字和关键字形式的运算符 (优先级 \"2\")
442                // 只添加关键字形式的运算符,不添加符号运算符
443                let having_keywords =
444                    vec!["AND", "OR", "NOT", "IN", "LIKE", "BETWEEN", "IS", "NULL"];
445                for keyword in having_keywords {
446                    let mut item = self.create_keyword_item(keyword);
447                    item.sort_text = Some(format!("2{}", keyword)); // Keywords after aggregate functions
448                    items.push(item);
449                }
450            }
451
452            crate::parser::CompletionContext::TableColumn => {
453                // 表名.列名:只补全特定表的列名
454                if let Some(tree) = &parse_result.tree {
455                    if let Some(node) = parser.get_node_at_position(tree, position) {
456                        if let Some(table_name) = parser.get_table_name_for_column(node, sql) {
457                            if let Some(schema) = schema {
458                                let aliases = parser.extract_aliases(tree, sql);
459
460                                // Resolve alias to real table name
461                                let real_table_name =
462                                    aliases.get(&table_name).unwrap_or(&table_name);
463
464                                if let Some(table) =
465                                    schema.tables.iter().find(|t| t.name == *real_table_name)
466                                {
467                                    for column in &table.columns {
468                                        items.push(self.create_column_item(column, None));
469                                    }
470                                }
471                            }
472                        }
473                    }
474                }
475            }
476
477            crate::parser::CompletionContext::Default => {
478                // 默认:返回所有关键字
479                let keywords = vec![
480                    "SELECT", "FROM", "WHERE", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP",
481                    "ALTER", "TABLE", "INDEX", "DATABASE", "SHOW", "DESCRIBE", "EXPLAIN", "JOIN",
482                    "INNER", "LEFT", "RIGHT", "OUTER", "ON", "GROUP", "BY", "ORDER", "HAVING",
483                    "LIMIT", "OFFSET", "UNION", "ALL", "DISTINCT", "AS", "AND", "OR", "NOT", "IN",
484                    "LIKE", "BETWEEN", "IS", "NULL", "TRUE", "FALSE",
485                ];
486
487                for keyword in keywords {
488                    items.push(self.create_keyword_item(keyword));
489                }
490
491                // 如果提供了 schema,添加表和列补全
492                if let Some(schema) = schema {
493                    for table in &schema.tables {
494                        items.push(self.create_table_item(table));
495                    }
496                }
497            }
498        }
499
500        items
501    }
502
503    async fn hover(&self, sql: &str, position: Position, schema: Option<&Schema>) -> Option<Hover> {
504        let mut parser = self.parser.lock().unwrap();
505        let parse_result = parser.parse(sql);
506
507        // 获取光标位置的节点
508        if let Some(tree) = &parse_result.tree {
509            if let Some(node) = parser.get_node_at_position(tree, position) {
510                let node_text = parser.node_text(node, sql);
511                let node_kind = node.kind();
512                let node_range = parser.node_range(node);
513
514                // 过滤关键字、操作符、分隔符
515                if crate::token::Keywords::is_keyword(&node_text)
516                    || crate::token::Operators::is_operator(&node_text)
517                    || crate::token::Delimiters::is_delimiter(&node_text)
518                {
519                    return None;
520                }
521
522                if let Some(schema) = schema {
523                    // 检查是否是表名
524                    let is_table = node_kind == "table_name"
525                        || node_kind == "table_reference"
526                        || node_kind == "table_identifier"
527                        || (node_kind == "identifier" && parser.is_in_from_context(node, sql));
528
529                    if is_table {
530                        if let Some(table) = schema.tables.iter().find(|t| t.name == node_text) {
531                            let mut info = format!("**Table**: `{}`\n\n", table.name);
532                            if let Some(comment) = &table.comment {
533                                info.push_str(&format!("{}\n\n", comment));
534                            }
535                            info.push_str(&format!("**Columns** ({})\n", table.columns.len()));
536                            for (idx, col) in table.columns.iter().take(10).enumerate() {
537                                info.push_str(&format!(
538                                    "- `{}`: {} {}\n",
539                                    col.name,
540                                    col.data_type,
541                                    if col.nullable { "" } else { "NOT NULL" }
542                                ));
543                                if idx == 9 && table.columns.len() > 10 {
544                                    info.push_str(&format!(
545                                        "- ... and {} more\n",
546                                        table.columns.len() - 10
547                                    ));
548                                    break;
549                                }
550                            }
551
552                            return Some(Hover {
553                                contents: tower_lsp::lsp_types::HoverContents::Markup(
554                                    tower_lsp::lsp_types::MarkupContent {
555                                        kind: tower_lsp::lsp_types::MarkupKind::Markdown,
556                                        value: info,
557                                    },
558                                ),
559                                range: Some(node_range),
560                            });
561                        }
562                    }
563
564                    // 检查是否是列名
565                    let is_column = node_kind == "column_name"
566                        || node_kind == "column_reference"
567                        || node_kind == "column_identifier"
568                        || (node_kind == "identifier" && parser.is_in_column_context(node, sql));
569
570                    if is_column {
571                        // 尝试获取表名(如果是 table.column 格式)
572                        let table_name = parser.get_table_name_for_column(node, sql);
573
574                        for table in &schema.tables {
575                            // 如果有明确的表名,只在该表中查找
576                            if let Some(ref tname) = table_name {
577                                if table.name != *tname {
578                                    continue;
579                                }
580                            }
581
582                            if let Some(column) = table.columns.iter().find(|c| c.name == node_text)
583                            {
584                                let mut info =
585                                    format!("**Column**: `{}.{}`\n\n", table.name, column.name);
586                                info.push_str(&format!("**Type**: `{}`\n", column.data_type));
587                                info.push_str(&format!(
588                                    "**Nullable**: {}\n",
589                                    if column.nullable { "Yes" } else { "No" }
590                                ));
591                                if let Some(comment) = &column.comment {
592                                    info.push_str(&format!("\n{}\n", comment));
593                                }
594
595                                return Some(Hover {
596                                    contents: tower_lsp::lsp_types::HoverContents::Markup(
597                                        tower_lsp::lsp_types::MarkupContent {
598                                            kind: tower_lsp::lsp_types::MarkupKind::Markdown,
599                                            value: info,
600                                        },
601                                    ),
602                                    range: Some(node_range),
603                                });
604                            }
605                        }
606                    }
607
608                    // 检查是否是函数名
609                    if node_kind == "function_name" || node_kind.contains("function") {
610                        if let Some(func) = schema.functions.iter().find(|f| f.name == node_text) {
611                            let mut info = format!("**Function**: `{}`\n\n", func.name);
612                            if let Some(desc) = &func.description {
613                                info.push_str(&format!("{}\n\n", desc));
614                            }
615                            info.push_str(&format!("**Returns**: `{}`\n", func.return_type));
616                            if !func.parameters.is_empty() {
617                                info.push_str("\n**Parameters**:\n");
618                                for param in &func.parameters {
619                                    info.push_str(&format!(
620                                        "- `{}`: `{}`{}\n",
621                                        param.name,
622                                        param.data_type,
623                                        if param.optional { " (optional)" } else { "" }
624                                    ));
625                                }
626                            }
627
628                            return Some(Hover {
629                                contents: tower_lsp::lsp_types::HoverContents::Markup(
630                                    tower_lsp::lsp_types::MarkupContent {
631                                        kind: tower_lsp::lsp_types::MarkupKind::Markdown,
632                                        value: info,
633                                    },
634                                ),
635                                range: Some(node_range),
636                            });
637                        }
638                    }
639                }
640            }
641        }
642
643        None
644    }
645
646    async fn goto_definition(
647        &self,
648        sql: &str,
649        position: Position,
650        schema: Option<&Schema>,
651    ) -> Option<Location> {
652        let mut parser = self.parser.lock().unwrap();
653        let parse_result = parser.parse(sql);
654
655        // 获取光标位置的节点
656        if let Some(tree) = &parse_result.tree {
657            if let Some(node) = parser.get_node_at_position(tree, position) {
658                let node_text = parser.node_text(node, sql);
659                let node_kind = node.kind();
660
661                // 过滤关键字、操作符、分隔符
662                if crate::token::Keywords::is_keyword(&node_text)
663                    || crate::token::Operators::is_operator(&node_text)
664                    || crate::token::Delimiters::is_delimiter(&node_text)
665                {
666                    return None;
667                }
668
669                // 判断是表名还是列名
670                let is_table = node_kind == "table_name"
671                    || node_kind == "table_reference"
672                    || node_kind == "table_identifier"
673                    || (node_kind == "identifier" && parser.is_in_from_context(node, sql));
674
675                let is_column = node_kind == "column_name"
676                    || node_kind == "column_reference"
677                    || node_kind == "column_identifier"
678                    || (node_kind == "identifier" && parser.is_in_column_context(node, sql));
679
680                // 如果是表名,查找表定义
681                if is_table {
682                    if let Some(schema) = schema {
683                        if let Some(table) = schema.tables.iter().find(|t| t.name == node_text) {
684                            // 使用表的源位置(如果有)
685                            let (uri, line) = if let Some((ref source_uri, source_line)) =
686                                table.source_location
687                            {
688                                (
689                                    tower_lsp::lsp_types::Url::parse(source_uri).unwrap_or_else(
690                                        |_| {
691                                            tower_lsp::lsp_types::Url::parse("file:///schema.sql")
692                                                .unwrap()
693                                        },
694                                    ),
695                                    source_line.saturating_sub(1), // 转换为0-indexed
696                                )
697                            } else if let Some(ref schema_uri) = schema.source_uri {
698                                // 回退到 schema 的源文件
699                                (
700                                    tower_lsp::lsp_types::Url::parse(schema_uri).unwrap_or_else(
701                                        |_| {
702                                            tower_lsp::lsp_types::Url::parse("file:///schema.sql")
703                                                .unwrap()
704                                        },
705                                    ),
706                                    0,
707                                )
708                            } else {
709                                // 默认虚拟位置
710                                (
711                                    tower_lsp::lsp_types::Url::parse("file:///schema.sql").unwrap(),
712                                    0,
713                                )
714                            };
715
716                            return Some(Location {
717                                uri,
718                                range: tower_lsp::lsp_types::Range {
719                                    start: tower_lsp::lsp_types::Position { line, character: 0 },
720                                    end: tower_lsp::lsp_types::Position {
721                                        line,
722                                        character: 100,
723                                    },
724                                },
725                            });
726                        }
727                    }
728                }
729
730                // 如果是列名,查找列定义
731                if is_column {
732                    if let Some(schema) = schema {
733                        // 检查是否是 table.column 格式
734                        let (table_name, column_name) =
735                            if let Some(table_name) = parser.get_table_name_for_column(node, sql) {
736                                (Some(table_name), node_text.clone())
737                            } else {
738                                // 查找列所属的表
739                                let tables = parser.extract_tables(tree, sql);
740                                let table_name = tables.first().cloned();
741                                (table_name, node_text.clone())
742                            };
743
744                        // 在 Schema 中查找列
745                        for table in &schema.tables {
746                            if let Some(ref tname) = table_name {
747                                if table.name == *tname
748                                    && table.columns.iter().any(|c| c.name == column_name)
749                                {
750                                    // 返回当前文档中列名第一次出现的位置
751                                    return Some(Location {
752                                        uri: tower_lsp::lsp_types::Url::parse("file:///schema.sql")
753                                            .unwrap_or_else(|_| {
754                                                tower_lsp::lsp_types::Url::parse("file:///")
755                                                    .unwrap()
756                                            }),
757                                        range: parser.node_range(node),
758                                    });
759                                }
760                            } else if table.columns.iter().any(|c| c.name == column_name) {
761                                // 在所有表中查找列
762                                return Some(Location {
763                                    uri: tower_lsp::lsp_types::Url::parse("file:///schema.sql")
764                                        .unwrap_or_else(|_| {
765                                            tower_lsp::lsp_types::Url::parse("file:///").unwrap()
766                                        }),
767                                    range: parser.node_range(node),
768                                });
769                            }
770                        }
771                    }
772                }
773            }
774        }
775
776        None
777    }
778
779    async fn references(
780        &self,
781        sql: &str,
782        position: Position,
783        _schema: Option<&Schema>,
784    ) -> Vec<Location> {
785        let mut parser = self.parser.lock().unwrap();
786        let parse_result = parser.parse(sql);
787
788        let mut locations = Vec::new();
789
790        // 获取光标位置的标识符
791        if let Some(tree) = &parse_result.tree {
792            if let Some(node) = parser.get_node_at_position(tree, position) {
793                let identifier = parser.node_text(node, sql);
794                let node_kind = node.kind();
795
796                // 过滤关键字、操作符、分隔符
797                if crate::token::Keywords::is_keyword(&identifier)
798                    || crate::token::Operators::is_operator(&identifier)
799                    || crate::token::Delimiters::is_delimiter(&identifier)
800                {
801                    return locations;
802                }
803
804                // 判断是表名还是列名
805                let is_table = node_kind == "table_name"
806                    || node_kind == "table_reference"
807                    || node_kind == "table_identifier"
808                    || (node_kind == "identifier" && parser.is_in_from_context(node, sql));
809
810                let is_column = node_kind == "column_name"
811                    || node_kind == "column_reference"
812                    || node_kind == "column_identifier"
813                    || (node_kind == "identifier" && parser.is_in_column_context(node, sql));
814
815                if is_table || is_column {
816                    // 在当前文档中查找所有引用
817                    let tokens = parser.tokenize(tree, sql);
818                    let current_uri = tower_lsp::lsp_types::Url::parse("file:///current.sql")
819                        .unwrap_or_else(|_| tower_lsp::lsp_types::Url::parse("file:///").unwrap());
820
821                    for token in tokens {
822                        // 匹配标识符(忽略大小写)
823                        if token.text.eq_ignore_ascii_case(&identifier)
824                            && !crate::token::Keywords::is_keyword(&token.text)
825                            && !crate::token::Operators::is_operator(&token.text)
826                            && !crate::token::Delimiters::is_delimiter(&token.text)
827                        {
828                            // 检查 token 类型,确保是标识符而不是关键字
829                            locations.push(Location {
830                                uri: current_uri.clone(),
831                                range: tower_lsp::lsp_types::Range {
832                                    start: token.position,
833                                    end: tower_lsp::lsp_types::Position {
834                                        line: token.position.line,
835                                        character: token.position.character
836                                            + token.text.len() as u32,
837                                    },
838                                },
839                            });
840                        }
841                    }
842                }
843            }
844        }
845
846        locations
847    }
848
849    async fn format(&self, sql: &str) -> String {
850        use sqlformat::{FormatOptions, Indent, QueryParams};
851        let options = FormatOptions {
852            indent: Indent::Spaces(2),
853            uppercase: true,
854            lines_between_queries: 1,
855        };
856        sqlformat::format(sql, &QueryParams::None, options)
857    }
858
859    async fn validate(&self, sql: &str, schema: Option<&Schema>) -> Vec<Diagnostic> {
860        self.parse(sql, schema).await
861    }
862}