1use std::fmt::{self, Debug};
17use std::hash::Hash;
18
19use crate::ast::display::{self, AstDisplay, AstFormatter};
20use crate::ast::fold::{Fold, FoldNode};
21use crate::ast::{
22 Ident, Statement, UnresolvedDatabaseName, UnresolvedItemName, UnresolvedObjectName,
23 UnresolvedSchemaName, Version,
24};
25
26pub trait AstInfo: Clone {
42 type NestedStatement: AstDisplay + Clone + Hash + Debug + Eq;
44 type ItemName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
47 type ColumnReference: AstDisplay + Clone + Hash + Debug + Eq + Ord;
53 type SchemaName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
55 type DatabaseName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
57 type ClusterName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
59 type DataType: AstDisplay + Clone + Hash + Debug + Eq + Ord;
61 type CteId: Clone + Hash + Debug + Eq + Ord;
63 type RoleName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
65 type NetworkPolicyName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
67 type ObjectName: AstDisplay + Clone + Hash + Debug + Eq + Ord;
69}
70
71#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, Default)]
72pub struct Raw;
73
74impl AstInfo for Raw {
75 type NestedStatement = Statement<Raw>;
76 type ItemName = RawItemName;
77 type ColumnReference = Ident;
78 type SchemaName = UnresolvedSchemaName;
79 type DatabaseName = UnresolvedDatabaseName;
80 type ClusterName = RawClusterName;
81 type DataType = RawDataType;
82 type CteId = ();
83 type RoleName = Ident;
84 type NetworkPolicyName = RawNetworkPolicyName;
85 type ObjectName = UnresolvedObjectName;
86}
87
88#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
89pub enum RawItemName {
90 Name(UnresolvedItemName),
91 Id(String, UnresolvedItemName, Option<Version>),
92}
93
94impl RawItemName {
95 pub fn name(&self) -> &UnresolvedItemName {
96 match self {
97 RawItemName::Name(name) => name,
98 RawItemName::Id(_, name, _) => name,
99 }
100 }
101
102 pub fn name_mut(&mut self) -> &mut UnresolvedItemName {
103 match self {
104 RawItemName::Name(name) => name,
105 RawItemName::Id(_, name, _) => name,
106 }
107 }
108}
109
110fn write_bracketed_id<W: fmt::Write>(f: &mut AstFormatter<W>, id: &str) {
112 let ident = Ident::new_unchecked(id);
113 if ident.has_only_bare_chars() && ident.as_keyword().is_none() {
116 f.write_str(id);
117 } else {
118 f.write_str(ident.to_ast_string_stable());
119 }
120}
121
122impl AstDisplay for RawItemName {
123 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
124 match self {
125 RawItemName::Name(o) => f.write_node(o),
126 RawItemName::Id(id, o, v) => {
127 f.write_str("[");
128 write_bracketed_id(f, id);
129 f.write_str(" AS ");
130 f.write_node(o);
131 if let Some(v) = v {
132 f.write_str(" VERSION ");
133 f.write_node(v);
134 }
135 f.write_str("]");
136 }
137 }
138 }
139}
140impl_display!(RawItemName);
141
142impl<T> FoldNode<Raw, T> for RawItemName
143where
144 T: AstInfo,
145{
146 type Folded = T::ItemName;
147
148 fn fold<F>(self, f: &mut F) -> Self::Folded
149 where
150 F: Fold<Raw, T>,
151 {
152 f.fold_item_name(self)
153 }
154}
155
156#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
157pub enum RawClusterName {
158 Unresolved(Ident),
159 Resolved(String),
160}
161
162impl AstDisplay for RawClusterName {
163 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
164 match self {
165 RawClusterName::Unresolved(id) => f.write_node(id),
166 RawClusterName::Resolved(id) => {
167 f.write_str("[");
168 write_bracketed_id(f, id);
169 f.write_str("]");
170 }
171 }
172 }
173}
174impl_display!(RawClusterName);
175
176impl<T> FoldNode<Raw, T> for RawClusterName
177where
178 T: AstInfo,
179{
180 type Folded = T::ClusterName;
181
182 fn fold<F>(self, f: &mut F) -> Self::Folded
183 where
184 F: Fold<Raw, T>,
185 {
186 f.fold_cluster_name(self)
187 }
188}
189
190#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
191pub enum RawNetworkPolicyName {
192 Unresolved(Ident),
193 Resolved(String),
194}
195
196impl AstDisplay for RawNetworkPolicyName {
197 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
198 match self {
199 RawNetworkPolicyName::Unresolved(id) => f.write_node(id),
200 RawNetworkPolicyName::Resolved(id) => {
201 f.write_str("[");
202 write_bracketed_id(f, id);
203 f.write_str("]");
204 }
205 }
206 }
207}
208impl_display!(RawNetworkPolicyName);
209
210impl<T> FoldNode<Raw, T> for RawNetworkPolicyName
211where
212 T: AstInfo,
213{
214 type Folded = T::NetworkPolicyName;
215
216 fn fold<F>(self, f: &mut F) -> Self::Folded
217 where
218 F: Fold<Raw, T>,
219 {
220 f.fold_network_policy_name(self)
221 }
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
226pub enum RawDataType {
227 Array(Box<RawDataType>),
229 List(Box<RawDataType>),
231 Map {
233 key_type: Box<RawDataType>,
234 value_type: Box<RawDataType>,
235 },
236 Other {
238 name: RawItemName,
239 typ_mod: Vec<i64>,
241 },
242}
243
244impl AstDisplay for RawDataType {
245 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
246 match self {
247 RawDataType::Array(ty) => {
248 f.write_node(&ty);
249 f.write_str("[]");
250 }
251 RawDataType::List(ty) => {
252 f.write_node(&ty);
253 f.write_str(" list");
254 }
255 RawDataType::Map {
256 key_type,
257 value_type,
258 } => {
259 f.write_str("map[");
260 f.write_node(&key_type);
261 f.write_str("=>");
262 f.write_node(&value_type);
263 f.write_str("]");
264 }
265 RawDataType::Other { name, typ_mod } => {
266 let first_ident_clashes = name
280 .name()
281 .0
282 .first()
283 .and_then(|id| id.as_keyword())
284 .map(data_type_keyword_needs_quoting)
285 .unwrap_or(false);
286 if first_ident_clashes {
287 f.write_str(&name.to_ast_string_stable());
288 } else {
289 f.write_node(name);
290 }
291 if typ_mod.len() > 0 {
292 f.write_str("(");
293 f.write_node(&display::comma_separated(typ_mod));
294 f.write_str(")");
295 }
296 }
297 }
298 }
299}
300impl_display!(RawDataType);
301
302fn data_type_keyword_needs_quoting(kw: mz_sql_lexer::keywords::Keyword) -> bool {
313 use mz_sql_lexer::keywords::*;
314 matches!(
315 kw,
316 MAP | STRING
317 | BIGINT
318 | SMALLINT
319 | DEC
320 | DECIMAL
321 | DOUBLE
322 | FLOAT
323 | INT
324 | INTEGER
325 | REAL
326 | BOOLEAN
327 | BYTES
328 | JSON
329 | CHAR
330 | CHARACTER
331 )
332}
333
334impl<T> FoldNode<Raw, T> for RawDataType
335where
336 T: AstInfo,
337{
338 type Folded = T::DataType;
339
340 fn fold<F>(self, f: &mut F) -> Self::Folded
341 where
342 F: Fold<Raw, T>,
343 {
344 f.fold_data_type(self)
345 }
346}