hyperdb_compile_check/
dry_run.rs1use hyperdb_api::{Error, Result, ResultSchema};
19
20use crate::db::CompileTimeDb;
21
22pub fn dry_run(db: &mut CompileTimeDb, user_sql: &str) -> Result<ResultSchema> {
32 let wrapped = format!("WITH __hdb_q AS ({user_sql}) SELECT * FROM __hdb_q LIMIT 0");
33 let mut rowset = db.conn.execute_query(&wrapped)?;
34
35 rowset.next_chunk()?;
38
39 rowset
40 .schema()
41 .ok_or_else(|| Error::Protocol("dry-run: schema missing after next_chunk".into()))
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::db::get_or_init;
48
49 #[test]
50 #[ignore = "requires HYPERD_PATH; run manually"]
51 fn dry_run_plain_select() {
52 let mut db = get_or_init().lock();
53 db.conn
54 .execute_command("CREATE TABLE IF NOT EXISTS _dr_test (id BIGINT, name TEXT)")
55 .unwrap();
56 let schema = dry_run(&mut db, "SELECT id, name FROM _dr_test").unwrap();
57 let names: Vec<_> = schema
58 .columns()
59 .iter()
60 .map(hyperdb_api::ResultColumn::name)
61 .collect();
62 assert_eq!(names, &["id", "name"]);
63 }
64
65 #[test]
66 #[ignore = "requires HYPERD_PATH; run manually"]
67 fn dry_run_cte_wrapper() {
68 let mut db = get_or_init().lock();
69 db.conn
70 .execute_command("CREATE TABLE IF NOT EXISTS _dr_cte (x INT, y TEXT)")
71 .unwrap();
72 let schema = dry_run(
73 &mut db,
74 "WITH src AS (SELECT x, y FROM _dr_cte) SELECT * FROM src",
75 )
76 .unwrap();
77 assert_eq!(schema.column_count(), 2);
78 }
79
80 #[test]
81 #[ignore = "requires HYPERD_PATH; run manually"]
82 fn dry_run_from_less_expression() {
83 let mut db = get_or_init().lock();
84 let schema = dry_run(&mut db, "SELECT 1 AS a, 'x' AS b").unwrap();
85 let names: Vec<_> = schema
86 .columns()
87 .iter()
88 .map(hyperdb_api::ResultColumn::name)
89 .collect();
90 assert_eq!(names, &["a", "b"]);
91 }
92
93 #[test]
94 #[ignore = "requires HYPERD_PATH; run manually"]
95 fn dry_run_bad_table_returns_error() {
96 let mut db = get_or_init().lock();
97 let err = dry_run(&mut db, "SELECT * FROM _nonexistent_xyz").unwrap_err();
98 assert_eq!(
99 err.sqlstate(),
100 Some("42P01"),
101 "expected undefined_table: {err}"
102 );
103 }
104}