1use serde::{Deserialize, Serialize};
2use crate::ast::{AggregateFunc, Cage, Condition, ModKind, Value};
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub enum Column {
7 Star,
9 Named(String),
11 Aliased { name: String, alias: String },
13 Aggregate { col: String, func: AggregateFunc },
15 Def {
17 name: String,
18 data_type: String,
19 constraints: Vec<Constraint>,
20 },
21 Mod {
23 kind: ModKind,
24 col: Box<Column>,
25 },
26 Window {
28 name: String,
29 func: String,
30 params: Vec<Value>,
31 partition: Vec<String>,
32 order: Vec<Cage>,
33 frame: Option<WindowFrame>,
34 },
35 Case {
37 when_clauses: Vec<(Condition, Value)>,
39 else_value: Option<Box<Value>>,
41 alias: Option<String>,
43 },
44 JsonAccess {
46 column: String,
48 path: String,
50 as_text: bool,
52 alias: Option<String>,
54 },
55 FunctionCall {
57 name: String,
59 args: Vec<String>,
61 alias: Option<String>,
63 },
64}
65
66impl std::fmt::Display for Column {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 match self {
69 Column::Star => write!(f, "*"),
70 Column::Named(name) => write!(f, "{}", name),
71 Column::Aliased { name, alias } => write!(f, "{} AS {}", name, alias),
72 Column::Aggregate { col, func } => write!(f, "{}({})", func, col),
73 Column::Def {
74 name,
75 data_type,
76 constraints,
77 } => {
78 write!(f, "{}:{}", name, data_type)?;
79 for c in constraints {
80 write!(f, "^{}", c)?;
81 }
82 Ok(())
83 }
84 Column::Mod { kind, col } => match kind {
85 ModKind::Add => write!(f, "+{}", col),
86 ModKind::Drop => write!(f, "-{}", col),
87 },
88 Column::Window { name, func, params, partition, order, frame } => {
89 write!(f, "{}:{}(", name, func)?;
90 for (i, p) in params.iter().enumerate() {
91 if i > 0 { write!(f, ", ")?; }
92 write!(f, "{}", p)?;
93 }
94 write!(f, ")")?;
95
96 if !partition.is_empty() {
98 write!(f, "{{Part=")?;
99 for (i, p) in partition.iter().enumerate() {
100 if i > 0 { write!(f, ",")?; }
101 write!(f, "{}", p)?;
102 }
103 if let Some(fr) = frame {
104 write!(f, ", Frame={:?}", fr)?; }
106 write!(f, "}}")?;
107 } else if frame.is_some() {
108 write!(f, "{{Frame={:?}}}", frame.as_ref().unwrap())?;
109 }
110
111 for _cage in order {
113 }
115 Ok(())
116 }
117 Column::Case { when_clauses, else_value, alias } => {
118 write!(f, "CASE")?;
119 for (cond, val) in when_clauses {
120 write!(f, " WHEN {} THEN {}", cond.column, val)?;
121 }
122 if let Some(e) = else_value {
123 write!(f, " ELSE {}", e)?;
124 }
125 write!(f, " END")?;
126 if let Some(a) = alias {
127 write!(f, " AS {}", a)?;
128 }
129 Ok(())
130 }
131 Column::JsonAccess { column, path, as_text, alias } => {
132 let op = if *as_text { "->>" } else { "->" };
133 write!(f, "{}{}{}", column, op, path)?;
134 if let Some(a) = alias {
135 write!(f, " AS {}", a)?;
136 }
137 Ok(())
138 }
139 Column::FunctionCall { name, args, alias } => {
140 write!(f, "{}({})", name.to_uppercase(), args.join(", "))?;
141 if let Some(a) = alias {
142 write!(f, " AS {}", a)?;
143 }
144 Ok(())
145 }
146 }
147 }
148}
149
150#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub enum Constraint {
153 PrimaryKey,
154 Unique,
155 Nullable,
156 Default(String),
158 Check(Vec<String>),
160 Comment(String),
162 Generated(ColumnGeneration),
164}
165
166#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
168pub enum ColumnGeneration {
169 Stored(String),
171 Virtual(String),
173}
174
175#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
177pub enum WindowFrame {
178 Rows { start: FrameBound, end: FrameBound },
180 Range { start: FrameBound, end: FrameBound },
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
186pub enum FrameBound {
187 UnboundedPreceding,
188 Preceding(i32),
189 CurrentRow,
190 Following(i32),
191 UnboundedFollowing,
192}
193
194impl std::fmt::Display for Constraint {
195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196 match self {
197 Constraint::PrimaryKey => write!(f, "pk"),
198 Constraint::Unique => write!(f, "uniq"),
199 Constraint::Nullable => write!(f, "?"),
200 Constraint::Default(val) => write!(f, "={}", val),
201 Constraint::Check(vals) => write!(f, "check({})", vals.join(",")),
202 Constraint::Comment(text) => write!(f, "comment(\"{}\")", text),
203 Constraint::Generated(generation) => match generation {
204 ColumnGeneration::Stored(expr) => write!(f, "gen({})", expr),
205 ColumnGeneration::Virtual(expr) => write!(f, "vgen({})", expr),
206 },
207 }
208 }
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
213pub struct IndexDef {
214 pub name: String,
216 pub table: String,
218 pub columns: Vec<String>,
220 pub unique: bool,
222}
223
224#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
226pub enum TableConstraint {
227 Unique(Vec<String>),
229 PrimaryKey(Vec<String>),
231}