1use crate::ast::{Action, CTEDef, Expr, GroupByMode, Qail};
4
5impl Qail {
6 pub fn to_cte(self, name: impl Into<String>) -> CTEDef {
7 let cte_name = name.into();
8 let columns: Vec<String> = self
9 .columns
10 .iter()
11 .filter_map(|c| match c {
12 Expr::Named(n) => Some(n.clone()),
13 Expr::Aliased { alias, .. } => Some(alias.clone()),
14 _ => None,
15 })
16 .collect();
17
18 CTEDef {
19 name: cte_name,
20 recursive: false,
21 columns,
22 base_query: Box::new(self),
23 recursive_query: None,
24 source_table: None,
25 }
26 }
27
28 pub fn with(self, name: impl Into<String>, query: Qail) -> Self {
29 self.with_cte(query.to_cte(name))
30 }
31
32 #[deprecated(
33 since = "0.13.0",
34 note = "Use .to_cte() for reusable CTEDef or .with() for inline CTE"
35 )]
36 pub fn as_cte(self, name: impl Into<String>) -> Self {
37 let cte_name = name.into();
38 let columns: Vec<String> = self
39 .columns
40 .iter()
41 .filter_map(|c| match c {
42 Expr::Named(n) => Some(n.clone()),
43 Expr::Aliased { alias, .. } => Some(alias.clone()),
44 _ => None,
45 })
46 .collect();
47
48 Self {
49 action: Action::With,
50 table: cte_name.clone(),
51 columns: vec![],
52 joins: vec![],
53 cages: vec![],
54 distinct: false,
55 index_def: None,
56 table_constraints: vec![],
57 set_ops: vec![],
58 having: vec![],
59 group_by_mode: GroupByMode::Simple,
60 distinct_on: vec![],
61 returning: None,
62 on_conflict: None,
63 source_query: None,
64 channel: None,
65 payload: None,
66 savepoint_name: None,
67 from_tables: vec![],
68 using_tables: vec![],
69 lock_mode: None,
70 fetch: None,
71 default_values: false,
72 overriding: None,
73 sample: None,
74 only_table: false,
75 vector: None,
76 score_threshold: None,
77 vector_name: None,
78 with_vector: false,
79 vector_size: None,
80 distance: None,
81 on_disk: None,
82 function_def: None,
83 trigger_def: None,
84 raw_value: None,
85 redis_ttl: None,
86 redis_set_condition: None,
87 ctes: vec![CTEDef {
88 name: cte_name,
89 recursive: false,
90 columns,
91 base_query: Box::new(self),
92 recursive_query: None,
93 source_table: None,
94 }],
95 }
96 }
97
98 pub fn recursive(mut self, recursive_part: Qail) -> Self {
99 if let Some(cte) = self.ctes.last_mut() {
100 cte.recursive = true;
101 cte.recursive_query = Some(Box::new(recursive_part));
102 }
103 self
104 }
105
106 pub fn from_cte(mut self, cte_name: impl Into<String>) -> Self {
107 if let Some(cte) = self.ctes.last_mut() {
108 cte.source_table = Some(cte_name.into());
109 }
110 self
111 }
112
113 pub fn select_from_cte(mut self, columns: &[&str]) -> Self {
114 self.columns = columns.iter().map(|c| Expr::Named(c.to_string())).collect();
115 self
116 }
117
118 pub fn with_cte(mut self, cte: CTEDef) -> Self {
119 self.ctes.push(cte);
120 self
121 }
122}