use alloc::vec::Vec;
use crate::create::parse_sequence_options;
use crate::{
Identifier, OptSpanned, QualifiedName, SequenceOption, Span, Spanned,
alter_table::{AlterTableOwner, parse_alter_owner},
keywords::Keyword,
lexer::Token,
parser::{ParseError, Parser},
qualified_name::parse_qualified_name_unreserved,
};
#[derive(Clone, Debug)]
pub enum AlterSequenceAction<'a> {
Options(Vec<SequenceOption<'a>>),
RenameTo {
rename_to_span: Span,
new_name: Identifier<'a>,
},
SetSchema {
set_schema_span: Span,
new_schema: Identifier<'a>,
},
OwnerTo {
owner_to_span: Span,
new_owner: AlterTableOwner<'a>,
},
}
impl<'a> Spanned for AlterSequenceAction<'a> {
fn span(&self) -> Span {
match self {
AlterSequenceAction::Options(options) => options.opt_span().unwrap(),
AlterSequenceAction::RenameTo {
rename_to_span,
new_name,
} => rename_to_span.join_span(new_name),
AlterSequenceAction::SetSchema {
set_schema_span,
new_schema,
} => set_schema_span.join_span(new_schema),
AlterSequenceAction::OwnerTo {
owner_to_span,
new_owner,
} => owner_to_span.join_span(new_owner),
}
}
}
#[derive(Clone, Debug)]
pub struct AlterSequence<'a> {
pub alter_sequence_span: Span,
pub if_exists: Option<Span>,
pub name: QualifiedName<'a>,
pub action: AlterSequenceAction<'a>,
}
impl<'a> Spanned for AlterSequence<'a> {
fn span(&self) -> Span {
self.alter_sequence_span
.join_span(&self.if_exists)
.join_span(&self.name)
.join_span(&self.action)
}
}
pub(crate) fn parse_alter_sequence<'a>(
parser: &mut Parser<'a, '_>,
alter_sequence_span: Span,
) -> Result<AlterSequence<'a>, ParseError> {
parser.postgres_only(&alter_sequence_span);
let if_exists = if let Some(if_span) = parser.skip_keyword(Keyword::IF) {
Some(parser.consume_keyword(Keyword::EXISTS)?.join_span(&if_span))
} else {
None
};
let name = parse_qualified_name_unreserved(parser)?;
let action = match &parser.token {
Token::Ident(_, Keyword::RENAME) => {
let rename_to_span = parser.consume_keywords(&[Keyword::RENAME, Keyword::TO])?;
let new_name = parser.consume_plain_identifier_unreserved()?;
AlterSequenceAction::RenameTo {
rename_to_span,
new_name,
}
}
Token::Ident(_, Keyword::SET) => {
let set_span = parser.consume_keyword(Keyword::SET)?;
if let Token::Ident(_, Keyword::SCHEMA) = parser.token {
let schema_span = parser.consume_keyword(Keyword::SCHEMA)?;
let new_schema = parser.consume_plain_identifier_unreserved()?;
AlterSequenceAction::SetSchema {
set_schema_span: set_span.join_span(&schema_span),
new_schema,
}
} else {
parser.expected_failure("'SCHEMA' after 'SET' in ALTER SEQUENCE")?
}
}
Token::Ident(_, Keyword::OWNER) => {
let owner_to_span = parser.consume_keywords(&[Keyword::OWNER, Keyword::TO])?;
let new_owner = parse_alter_owner(parser)?;
AlterSequenceAction::OwnerTo {
owner_to_span,
new_owner,
}
}
_ => {
let options = parse_sequence_options(parser)?;
if options.is_empty() {
parser.expected_failure("sequence options, 'RENAME TO', 'SET SCHEMA' or 'OWNER TO' after ALTER SEQUENCE")?;
}
AlterSequenceAction::Options(options)
}
};
Ok(AlterSequence {
alter_sequence_span,
if_exists,
name,
action,
})
}