1use crate::ast::{CTEDef, Expr, Qail};
4
5impl Qail {
6 pub fn to_cte(self, name: impl Into<String>) -> CTEDef {
8 let cte_name = name.into();
9 let columns: Vec<String> = self
10 .columns
11 .iter()
12 .filter_map(|c| match c {
13 Expr::Named(n) => Some(n.clone()),
14 Expr::Aliased { alias, .. } => Some(alias.clone()),
15 _ => None,
16 })
17 .collect();
18
19 CTEDef {
20 name: cte_name,
21 recursive: false,
22 columns,
23 base_query: Box::new(self),
24 recursive_query: None,
25 source_table: None,
26 }
27 }
28
29 pub fn with(self, name: impl Into<String>, query: Qail) -> Self {
31 self.with_cte(query.to_cte(name))
32 }
33
34 pub fn recursive(mut self, recursive_part: Qail) -> Self {
36 if let Some(cte) = self.ctes.last_mut() {
37 cte.recursive = true;
38 cte.recursive_query = Some(Box::new(recursive_part));
39 }
40 self
41 }
42
43 pub fn from_cte(mut self, cte_name: impl Into<String>) -> Self {
45 if let Some(cte) = self.ctes.last_mut() {
46 cte.source_table = Some(cte_name.into());
47 }
48 self
49 }
50
51 pub fn select_from_cte(mut self, columns: &[&str]) -> Self {
53 self.columns = columns.iter().map(|c| Expr::Named(c.to_string())).collect();
54 self
55 }
56
57 pub fn with_cte(mut self, cte: CTEDef) -> Self {
59 self.ctes.push(cte);
60 self
61 }
62}