1use alloc::vec::Vec;
14
15use crate::{
16 Identifier, OptSpanned, QualifiedName, SString, Span, Spanned,
17 alter_table::AlterTableOwner,
18 data_type::{DataType, DataTypeContext, parse_data_type},
19 drop::{CascadeOrRestrict, parse_cascade_or_restrict},
20 expression::{Expression, PRIORITY_MAX, parse_expression_unreserved},
21 keywords::Keyword,
22 lexer::Token,
23 parser::{ParseError, Parser},
24 qualified_name::parse_qualified_name_unreserved,
25};
26
27#[derive(Clone, Debug)]
29pub enum AlterTypeAction<'a> {
30 OwnerTo {
32 owner_to_span: Span,
33 new_owner: AlterTableOwner<'a>,
34 },
35 RenameTo {
37 rename_to_span: Span,
38 new_name: Identifier<'a>,
39 },
40 SetSchema {
42 set_schema_span: Span,
43 new_schema: QualifiedName<'a>,
44 },
45 RenameAttribute {
47 rename_attribute_span: Span,
48 attribute_name: Identifier<'a>,
49 to_span: Span,
50 new_attribute_name: Identifier<'a>,
51 cascade_or_restrict: Option<CascadeOrRestrict>,
52 },
53 AddValue {
55 add_value_span: Span,
56 if_not_exists_span: Option<Span>, new_enum_value: SString<'a>,
58 placement: Option<(Span, SString<'a>)>, },
60 RenameValue {
62 rename_value_span: Span,
63 existing_enum_value: SString<'a>,
64 to_span: Span,
65 new_enum_value: SString<'a>,
66 },
67 Attributes { items: Vec<AttributeAction<'a>> },
71 SetProperties {
73 set_span: Span,
74 properties: Vec<(Identifier<'a>, Expression<'a>)>,
75 },
76}
77
78impl<'a> Spanned for AlterTypeAction<'a> {
79 fn span(&self) -> Span {
80 match self {
81 AlterTypeAction::OwnerTo {
82 owner_to_span,
83 new_owner,
84 } => owner_to_span.join_span(new_owner),
85 AlterTypeAction::RenameTo {
86 rename_to_span,
87 new_name,
88 } => rename_to_span.join_span(new_name),
89 AlterTypeAction::SetSchema {
90 set_schema_span,
91 new_schema,
92 } => set_schema_span.join_span(new_schema),
93 AlterTypeAction::RenameAttribute {
94 rename_attribute_span,
95 attribute_name,
96 to_span,
97 new_attribute_name,
98 cascade_or_restrict,
99 } => rename_attribute_span
100 .join_span(attribute_name)
101 .join_span(to_span)
102 .join_span(new_attribute_name)
103 .join_span(cascade_or_restrict),
104 AlterTypeAction::AddValue {
105 add_value_span,
106 if_not_exists_span,
107 new_enum_value,
108 placement,
109 } => add_value_span
110 .join_span(if_not_exists_span)
111 .join_span(new_enum_value)
112 .join_span(placement),
113 AlterTypeAction::RenameValue {
114 rename_value_span,
115 existing_enum_value,
116 to_span,
117 new_enum_value,
118 } => rename_value_span
119 .join_span(existing_enum_value)
120 .join_span(to_span)
121 .join_span(new_enum_value),
122 AlterTypeAction::Attributes { items } => items.opt_span().expect("Empty attributes"),
123 AlterTypeAction::SetProperties {
124 set_span,
125 properties,
126 } => set_span.join_span(properties),
127 }
128 }
129}
130
131#[derive(Clone, Debug)]
133pub enum AttributeAction<'a> {
134 Add {
136 add_attribute_span: Span,
137 attribute_name: Identifier<'a>,
138 data_type: DataType<'a>,
139 collate: Option<(Span, QualifiedName<'a>)>,
140 cascade_or_restrict: Option<CascadeOrRestrict>,
141 },
142 Drop {
144 drop_attribute_span: Span,
145 if_exists_span: Option<Span>, attribute_name: Identifier<'a>,
147 cascade_or_restrict: Option<CascadeOrRestrict>,
148 },
149 Alter {
151 alter_attribute_span: Span,
152 attribute_name: Identifier<'a>,
153 set_data_span: Option<Span>, type_span: Span,
155 data_type: DataType<'a>,
156 collate: Option<(Span, QualifiedName<'a>)>,
157 cascade_or_restrict: Option<CascadeOrRestrict>,
158 },
159}
160
161impl<'a> Spanned for AttributeAction<'a> {
162 fn span(&self) -> Span {
163 match self {
164 AttributeAction::Add {
165 add_attribute_span,
166 attribute_name,
167 data_type,
168 collate,
169 cascade_or_restrict,
170 } => add_attribute_span
171 .join_span(attribute_name)
172 .join_span(data_type)
173 .join_span(collate)
174 .join_span(cascade_or_restrict),
175 AttributeAction::Drop {
176 drop_attribute_span,
177 if_exists_span,
178 attribute_name,
179 cascade_or_restrict,
180 } => drop_attribute_span
181 .join_span(if_exists_span)
182 .join_span(attribute_name)
183 .join_span(cascade_or_restrict),
184 AttributeAction::Alter {
185 alter_attribute_span,
186 attribute_name,
187 set_data_span,
188 type_span,
189 data_type,
190 collate,
191 cascade_or_restrict,
192 } => alter_attribute_span
193 .join_span(attribute_name)
194 .join_span(set_data_span)
195 .join_span(type_span)
196 .join_span(data_type)
197 .join_span(collate)
198 .join_span(cascade_or_restrict),
199 }
200 }
201}
202
203#[derive(Clone, Debug)]
205pub struct AlterType<'a> {
206 pub alter_type_span: Span,
208 pub name: QualifiedName<'a>,
210 pub action: AlterTypeAction<'a>,
212}
213
214impl<'a> Spanned for AlterType<'a> {
215 fn span(&self) -> Span {
216 self.alter_type_span
217 .join_span(&self.name)
218 .join_span(&self.action)
219 }
220}
221
222pub(crate) fn parse_alter_type<'a>(
223 parser: &mut Parser<'a, '_>,
224 alter_type_span: Span,
225) -> Result<AlterType<'a>, ParseError> {
226 parser.postgres_only(&alter_type_span);
227 let name = parse_qualified_name_unreserved(parser)?;
228
229 let action = match &parser.token {
230 Token::Ident(_, Keyword::OWNER) => {
231 let owner_to_span = parser.consume_keywords(&[Keyword::OWNER, Keyword::TO])?;
232 let new_owner = crate::alter_table::parse_alter_owner(parser)?;
233 AlterTypeAction::OwnerTo {
234 owner_to_span,
235 new_owner,
236 }
237 }
238 Token::Ident(_, Keyword::RENAME) => {
239 let rename_span = parser.consume_keyword(Keyword::RENAME)?;
240 match &parser.token {
241 Token::Ident(_, Keyword::TO) => {
242 let to_span = parser.consume_keyword(Keyword::TO)?;
244 let rename_to_span = rename_span.join_span(&to_span);
245 let new_name = parser.consume_plain_identifier_unreserved()?;
246 AlterTypeAction::RenameTo {
247 rename_to_span,
248 new_name,
249 }
250 }
251 Token::Ident(_, Keyword::ATTRIBUTE) => {
252 let attribute_span = parser.consume_keyword(Keyword::ATTRIBUTE)?;
254 let rename_attribute_span = rename_span.join_span(&attribute_span);
255 let attribute_name = parser.consume_plain_identifier_unreserved()?;
256 let to_span = parser.consume_keyword(Keyword::TO)?;
257 let new_attribute_name = parser.consume_plain_identifier_unreserved()?;
258 let cascade_or_restrict = parse_cascade_or_restrict(parser);
259 AlterTypeAction::RenameAttribute {
260 rename_attribute_span,
261 attribute_name,
262 to_span,
263 new_attribute_name,
264 cascade_or_restrict,
265 }
266 }
267 Token::Ident(_, Keyword::VALUE) => {
268 let value_span = parser.consume_keyword(Keyword::VALUE)?;
270 let rename_value_span = rename_span.join_span(&value_span);
271 let existing_enum_value = parser.consume_string()?;
272 let to_span = parser.consume_keyword(Keyword::TO)?;
273 let new_enum_value = parser.consume_string()?;
274 AlterTypeAction::RenameValue {
275 rename_value_span,
276 existing_enum_value,
277 to_span,
278 new_enum_value,
279 }
280 }
281 _ => parser.expected_failure("'TO', 'ATTRIBUTE', or 'VALUE' after 'RENAME'")?,
282 }
283 }
284 Token::Ident(_, Keyword::SET) => {
285 let set_span = parser.consume_keyword(Keyword::SET)?;
286 match &parser.token {
287 Token::Ident(_, Keyword::SCHEMA) => {
288 let schema_span = parser.consume_keyword(Keyword::SCHEMA)?;
290 let set_schema_span = set_span.join_span(&schema_span);
291 let new_schema = parse_qualified_name_unreserved(parser)?;
292 AlterTypeAction::SetSchema {
293 set_schema_span,
294 new_schema,
295 }
296 }
297 Token::LParen => {
298 parser.consume_token(Token::LParen)?;
300 let mut properties = Vec::new();
301 loop {
302 let property = parser.consume_plain_identifier_unreserved()?;
303 parser.consume_token(Token::Eq)?;
304 let value = parse_expression_unreserved(parser, PRIORITY_MAX)?;
305 properties.push((property, value));
306 if parser.skip_token(Token::Comma).is_none() {
307 break;
308 }
309 }
310 parser.consume_token(Token::RParen)?;
311 AlterTypeAction::SetProperties {
312 set_span,
313 properties,
314 }
315 }
316 _ => parser.expected_failure("'SCHEMA' or '(' after 'SET'")?,
317 }
318 }
319 Token::Ident(_, Keyword::ADD) => {
320 let add_span = parser.consume_keyword(Keyword::ADD)?;
321 match &parser.token {
322 Token::Ident(_, Keyword::VALUE) => {
323 let value_span = parser.consume_keyword(Keyword::VALUE)?;
325 let add_value_span = add_span.join_span(&value_span);
326 let if_not_exists_span = if let Some(if_span) = parser.skip_keyword(Keyword::IF)
327 {
328 Some(
329 parser
330 .consume_keywords(&[Keyword::NOT, Keyword::EXISTS])?
331 .join_span(&if_span),
332 )
333 } else {
334 None
335 };
336 let new_enum_value = parser.consume_string()?;
337 let placement = if let Some(before_span) = parser.skip_keyword(Keyword::BEFORE)
338 {
339 let neighbor = parser.consume_string()?;
340 Some((before_span, neighbor))
341 } else if let Some(after_span) = parser.skip_keyword(Keyword::AFTER) {
342 let neighbor = parser.consume_string()?;
343 Some((after_span, neighbor))
344 } else {
345 None
346 };
347 AlterTypeAction::AddValue {
348 add_value_span,
349 if_not_exists_span,
350 new_enum_value,
351 placement,
352 }
353 }
354 Token::Ident(_, Keyword::ATTRIBUTE) => {
355 let mut items = Vec::new();
357 loop {
358 items.push(parse_attribute_action(parser)?);
359 if parser.skip_token(Token::Comma).is_none() {
360 break;
361 }
362 }
363 AlterTypeAction::Attributes { items }
364 }
365 _ => parser.expected_failure("'VALUE' or 'ATTRIBUTE' after 'ADD'")?,
366 }
367 }
368 Token::Ident(_, Keyword::DROP) => {
369 let mut items = Vec::new();
371 loop {
372 items.push(parse_attribute_action(parser)?);
373 if parser.skip_token(Token::Comma).is_none() {
374 break;
375 }
376 }
377 AlterTypeAction::Attributes { items }
378 }
379 Token::Ident(_, Keyword::ALTER) => {
380 let mut items = Vec::new();
382 loop {
383 items.push(parse_attribute_action(parser)?);
384 if parser.skip_token(Token::Comma).is_none() {
385 break;
386 }
387 }
388 AlterTypeAction::Attributes { items }
389 }
390 _ => parser.expected_failure(
391 "'OWNER', 'RENAME', 'SET', 'ADD', 'DROP', or 'ALTER' after type name",
392 )?,
393 };
394
395 Ok(AlterType {
396 alter_type_span,
397 name,
398 action,
399 })
400}
401
402fn parse_attribute_action<'a>(
403 parser: &mut Parser<'a, '_>,
404) -> Result<AttributeAction<'a>, ParseError> {
405 match &parser.token {
406 Token::Ident(_, Keyword::ADD) => {
407 let add_attribute_span =
409 parser.consume_keywords(&[Keyword::ADD, Keyword::ATTRIBUTE])?;
410 let attribute_name = parser.consume_plain_identifier_unreserved()?;
411 let data_type = parse_data_type(parser, DataTypeContext::Column)?;
412 let collate = if let Some(collate_span) = parser.skip_keyword(Keyword::COLLATE) {
413 let collation = parse_qualified_name_unreserved(parser)?;
414 Some((collate_span, collation))
415 } else {
416 None
417 };
418 let cascade_or_restrict = parse_cascade_or_restrict(parser);
419 Ok(AttributeAction::Add {
420 add_attribute_span,
421 attribute_name,
422 data_type,
423 collate,
424 cascade_or_restrict,
425 })
426 }
427 Token::Ident(_, Keyword::DROP) => {
428 let drop_attribute_span =
430 parser.consume_keywords(&[Keyword::DROP, Keyword::ATTRIBUTE])?;
431 let if_exists_span = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
432 Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&if_span))
433 } else {
434 None
435 };
436 let attribute_name = parser.consume_plain_identifier_unreserved()?;
437 let cascade_or_restrict = parse_cascade_or_restrict(parser);
438 Ok(AttributeAction::Drop {
439 drop_attribute_span,
440 if_exists_span,
441 attribute_name,
442 cascade_or_restrict,
443 })
444 }
445 Token::Ident(_, Keyword::ALTER) => {
446 let alter_attribute_span =
448 parser.consume_keywords(&[Keyword::ALTER, Keyword::ATTRIBUTE])?;
449 let attribute_name = parser.consume_plain_identifier_unreserved()?;
450 let set_data_span = if let Some(set_span) = parser.skip_keyword(Keyword::SET) {
451 Some(parser.consume_keyword(Keyword::DATA)?.join_span(&set_span))
452 } else {
453 None
454 };
455 let type_span = parser.consume_keyword(Keyword::TYPE)?;
456 let data_type = parse_data_type(parser, DataTypeContext::Column)?;
457 let collate = if let Some(collate_span) = parser.skip_keyword(Keyword::COLLATE) {
458 let collation = parse_qualified_name_unreserved(parser)?;
459 Some((collate_span, collation))
460 } else {
461 None
462 };
463 let cascade_or_restrict = parse_cascade_or_restrict(parser);
464 Ok(AttributeAction::Alter {
465 alter_attribute_span,
466 attribute_name,
467 set_data_span,
468 type_span,
469 data_type,
470 collate,
471 cascade_or_restrict,
472 })
473 }
474 _ => parser.expected_failure("'ADD', 'DROP', or 'ALTER' for attribute action"),
475 }
476}