flowscope_core/parser/
mod.rs

1use crate::error::ParseError;
2use crate::types::Dialect;
3use sqlparser::ast::Statement;
4use sqlparser::parser::Parser;
5
6/// Parse SQL using the specified dialect
7pub fn parse_sql_with_dialect(sql: &str, dialect: Dialect) -> Result<Vec<Statement>, ParseError> {
8    let sqlparser_dialect = dialect.to_sqlparser_dialect();
9    let statements = Parser::parse_sql(sqlparser_dialect.as_ref(), sql)?;
10    Ok(statements)
11}
12
13/// Parse SQL using the generic dialect (legacy compatibility)
14pub fn parse_sql(sql: &str) -> Result<Vec<Statement>, ParseError> {
15    parse_sql_with_dialect(sql, Dialect::Generic)
16}
17
18#[cfg(test)]
19mod tests {
20    use super::*;
21
22    #[test]
23    fn test_parse_valid_select() {
24        let sql = "SELECT * FROM users";
25        let result = parse_sql(sql);
26        assert!(result.is_ok());
27        let statements = result.unwrap();
28        assert_eq!(statements.len(), 1);
29    }
30
31    #[test]
32    fn test_parse_invalid_sql() {
33        let sql = "SELECT * FROM";
34        let result = parse_sql(sql);
35        assert!(result.is_err());
36    }
37
38    #[test]
39    fn test_parse_multiple_statements() {
40        let sql = "SELECT * FROM users; SELECT * FROM orders;";
41        let result = parse_sql(sql);
42        assert!(result.is_ok());
43        let statements = result.unwrap();
44        assert_eq!(statements.len(), 2);
45    }
46
47    #[test]
48    fn test_parse_with_postgres_dialect() {
49        let sql = "SELECT * FROM users WHERE name ILIKE '%test%'";
50        let result = parse_sql_with_dialect(sql, Dialect::Postgres);
51        assert!(result.is_ok());
52    }
53
54    #[test]
55    fn test_parse_with_snowflake_dialect() {
56        let sql = "SELECT * FROM db.schema.table";
57        let result = parse_sql_with_dialect(sql, Dialect::Snowflake);
58        assert!(result.is_ok());
59    }
60
61    #[test]
62    fn test_parse_with_bigquery_dialect() {
63        let sql = "SELECT * FROM `project.dataset.table`";
64        let result = parse_sql_with_dialect(sql, Dialect::Bigquery);
65        assert!(result.is_ok());
66    }
67
68    #[test]
69    fn test_parse_cte() {
70        let sql = r#"
71            WITH active_users AS (
72                SELECT * FROM users WHERE active = true
73            )
74            SELECT * FROM active_users
75        "#;
76        let result = parse_sql(sql);
77        assert!(result.is_ok());
78    }
79
80    #[test]
81    fn test_parse_insert_select() {
82        let sql = "INSERT INTO archive SELECT * FROM users WHERE deleted = true";
83        let result = parse_sql(sql);
84        assert!(result.is_ok());
85    }
86
87    #[test]
88    fn test_parse_create_table_as() {
89        let sql = "CREATE TABLE users_backup AS SELECT * FROM users";
90        let result = parse_sql(sql);
91        assert!(result.is_ok());
92    }
93
94    #[test]
95    fn test_parse_union() {
96        let sql = "SELECT id FROM users UNION ALL SELECT id FROM admins";
97        let result = parse_sql(sql);
98        assert!(result.is_ok());
99    }
100}