sz_orm_explain/
dialect.rs1use crate::{ExplainDialect, ExplainError, ExplainParser, ExplainPlan};
7
8pub fn parse_explain(dialect: ExplainDialect, raw: &str) -> Result<ExplainPlan, ExplainError> {
19 crate::parser_for(dialect)?.parse(raw)
20}
21
22pub fn get_parser(dialect: ExplainDialect) -> Result<Box<dyn ExplainParser>, ExplainError> {
24 crate::parser_for(dialect)
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 use crate::{ExplainDialect, ScanType};
31
32 #[test]
33 fn mysql_parses() {
34 let plan = parse_explain(
35 ExplainDialect::MySql,
36 "| 1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 1150 | Using where |",
37 )
38 .unwrap();
39 assert_eq!(plan.scan_type, ScanType::FullTable);
40 assert_eq!(plan.table, "users");
41 }
42
43 #[test]
44 fn postgres_parses() {
45 let plan = parse_explain(
46 ExplainDialect::Postgres,
47 "Index Scan using t_pkey on t (cost=0.29..8.31 rows=1 width=36)",
48 )
49 .unwrap();
50 assert_eq!(plan.scan_type, ScanType::IndexRange);
51 assert_eq!(plan.index.as_deref(), Some("t_pkey"));
52 }
53
54 #[test]
55 fn sqlite_parses() {
56 let plan = parse_explain(ExplainDialect::Sqlite, "QUERY PLAN\n|--SCAN users").unwrap();
57 assert_eq!(plan.scan_type, ScanType::FullTable);
58 }
59
60 #[test]
61 fn oracle_parses() {
62 let plan = parse_explain(
63 ExplainDialect::Oracle,
64 "| 1 | TABLE ACCESS FULL | USERS | 1150 | 40250 | 21 |",
65 )
66 .unwrap();
67 assert_eq!(plan.scan_type, ScanType::FullTable);
68 }
69
70 #[test]
71 fn mssql_parses() {
72 let plan = parse_explain(
73 ExplainDialect::Mssql,
74 "|--Table Scan(OBJECT:([db].[dbo].[users]))",
75 )
76 .unwrap();
77 assert_eq!(plan.scan_type, ScanType::FullTable);
78 }
79
80 #[test]
81 fn all_dialects_have_parser() {
82 for d in [
83 ExplainDialect::MySql,
84 ExplainDialect::Postgres,
85 ExplainDialect::Sqlite,
86 ExplainDialect::Oracle,
87 ExplainDialect::Mssql,
88 ] {
89 assert!(crate::parser_for(d).is_ok(), "missing parser for {d:?}");
90 }
91 }
92}