@@ -13,11 +13,12 @@ use alloc::vec::Vec;
1313// limitations under the License.
1414use crate :: {
1515 data_type:: parse_data_type,
16+ expression:: parse_expression,
1617 keywords:: Keyword ,
1718 lexer:: Token ,
1819 parser:: { ParseError , Parser } ,
1920 qualified_name:: parse_qualified_name,
20- DataType , Identifier , QualifiedName , SString , Span , Spanned , Statement ,
21+ DataType , Expression , Identifier , QualifiedName , SString , Span , Spanned , Statement ,
2122} ;
2223
2324/// Option on an index
@@ -132,6 +133,43 @@ impl<'a> Spanned for IndexCol<'a> {
132133 }
133134}
134135
136+ /// Enum of alterations to perform on a column
137+ #[ derive( Clone , Debug ) ]
138+ pub enum AlterColumnAction < ' a > {
139+ SetDefault {
140+ set_default_span : Span ,
141+ value : Expression < ' a > ,
142+ } ,
143+ DropDefault {
144+ drop_default_span : Span ,
145+ } ,
146+ Type {
147+ type_span : Span ,
148+ type_ : DataType < ' a > ,
149+ } ,
150+ SetNotNull {
151+ set_not_null_span : Span ,
152+ } ,
153+ DropNotNull {
154+ drop_not_null_span : Span ,
155+ } ,
156+ }
157+
158+ impl < ' a > Spanned for AlterColumnAction < ' a > {
159+ fn span ( & self ) -> Span {
160+ match self {
161+ AlterColumnAction :: SetDefault {
162+ set_default_span,
163+ value,
164+ } => set_default_span. join_span ( value) ,
165+ AlterColumnAction :: DropDefault { drop_default_span } => drop_default_span. clone ( ) ,
166+ AlterColumnAction :: Type { type_span, type_ } => type_span. join_span ( type_) ,
167+ AlterColumnAction :: SetNotNull { set_not_null_span } => set_not_null_span. clone ( ) ,
168+ AlterColumnAction :: DropNotNull { drop_not_null_span } => drop_not_null_span. clone ( ) ,
169+ }
170+ }
171+ }
172+
135173/// Enum of alterations to perform on a table
136174#[ derive( Clone , Debug ) ]
137175pub enum AlterSpecification < ' a > {
@@ -183,7 +221,7 @@ pub enum AlterSpecification<'a> {
183221 } ,
184222 /// Modify a column
185223 Modify {
186- // Span of "MODIFY"
224+ /// Span of "MODIFY"
187225 modify_span : Span ,
188226 /// Span of "IF EXISTS" if specified
189227 if_exists : Option < Span > ,
@@ -192,6 +230,21 @@ pub enum AlterSpecification<'a> {
192230 /// New definition of column
193231 definition : DataType < ' a > ,
194232 } ,
233+ DropColumn {
234+ /// Span of "DROP COLUMN"
235+ drop_column_span : Span ,
236+ /// Name of column to drop
237+ column : Identifier < ' a > ,
238+ /// Span of "CASCADE" if specified
239+ cascade : Option < Span > ,
240+ } ,
241+ AlterColumn {
242+ /// Span of "ALTER COLUMN"
243+ alter_column_span : Span ,
244+ /// Name of column to drop
245+ column : Identifier < ' a > ,
246+ alter_column_action : AlterColumnAction < ' a > ,
247+ } ,
195248 /// Modify a column
196249 OwnerTo {
197250 // Span of "OWNER TO"
@@ -259,6 +312,18 @@ impl<'a> Spanned for AlterSpecification<'a> {
259312 . join_span ( col)
260313 . join_span ( definition) ,
261314 AlterSpecification :: OwnerTo { span, owner } => span. join_span ( owner) ,
315+ AlterSpecification :: DropColumn {
316+ drop_column_span,
317+ column : col,
318+ cascade,
319+ } => drop_column_span. join_span ( col) . join_span ( cascade) ,
320+ AlterSpecification :: AlterColumn {
321+ alter_column_span,
322+ column : col,
323+ alter_column_action,
324+ } => alter_column_span
325+ . join_span ( col)
326+ . join_span ( alter_column_action) ,
262327 }
263328 }
264329}
@@ -541,8 +606,8 @@ fn parse_add_alter_specification<'a>(
541606/// Represent an alter table statement
542607/// ```
543608/// # use sql_parse::{SQLDialect, SQLArguments, ParseOptions, parse_statements, AlterTable, Statement, Issues};
544- /// # let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
545- /// #
609+ /// let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
610+ ///
546611/// let sql = "ALTER TABLE `t1`
547612/// MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,
548613/// ADD CONSTRAINT `t1_t2` FOREIGN KEY (`two`) REFERENCES `t2` (`id`);";
@@ -557,7 +622,24 @@ fn parse_add_alter_specification<'a>(
557622/// };
558623///
559624/// assert!(alter.table.identifier.as_str() == "t1");
560- /// println!("{:#?}", alter.alter_specifications)
625+ /// println!("{:#?}", alter.alter_specifications);
626+ ///
627+ /// let options = ParseOptions::new().dialect(SQLDialect::PostgreSQL);
628+ /// let sql = "ALTER TABLE t1
629+ /// ALTER COLUMN id DROP NOT NULL,
630+ /// ALTER COLUMN id SET NOT NULL,
631+ /// ALTER COLUMN id SET DEFAULT 47,
632+ /// ALTER COLUMN id DROP DEFAULT,
633+ /// ALTER COLUMN id TYPE int;";
634+ ///
635+ /// let mut issues = Issues::new(sql);
636+ /// let mut stmts = parse_statements(sql, &mut issues, &options);
637+ ///
638+ /// # assert!(issues.is_ok());
639+ /// let alter: AlterTable = match stmts.pop() {
640+ /// Some(Statement::AlterTable(a)) => a,
641+ /// _ => panic!("We should get an alter table statement")
642+ /// };
561643///
562644#[ derive( Clone , Debug ) ]
563645pub struct AlterTable < ' a > {
@@ -633,6 +715,73 @@ fn parse_alter_table<'a>(
633715 let owner = parser. consume_plain_identifier ( ) ?;
634716 AlterSpecification :: OwnerTo { span, owner }
635717 }
718+ Token :: Ident ( _, Keyword :: DROP ) => {
719+ let drop_column_span =
720+ parser. consume_keywords ( & [ Keyword :: DROP , Keyword :: COLUMN ] ) ?;
721+ let column = parser. consume_plain_identifier ( ) ?;
722+ let cascade = parser. skip_keyword ( Keyword :: CASCADE ) ;
723+ AlterSpecification :: DropColumn {
724+ drop_column_span,
725+ column,
726+ cascade,
727+ }
728+ }
729+ Token :: Ident ( _, Keyword :: ALTER ) => {
730+ let span = parser. consume_keywords ( & [ Keyword :: ALTER , Keyword :: COLUMN ] ) ?;
731+ let column = parser. consume_plain_identifier ( ) ?;
732+
733+ let alter_column_action = match parser. token {
734+ Token :: Ident ( _, Keyword :: SET ) => {
735+ let set_span = parser. consume ( ) ;
736+ match parser. token {
737+ Token :: Ident ( _, Keyword :: DEFAULT ) => {
738+ let set_default_span = parser. consume ( ) . join_span ( & set_span) ;
739+ let value = parse_expression ( parser, false ) ?;
740+ AlterColumnAction :: SetDefault {
741+ set_default_span,
742+ value,
743+ }
744+ }
745+ Token :: Ident ( _, Keyword :: NOT ) => {
746+ let set_not_null_span = set_span. join_span (
747+ & parser. consume_keywords ( & [ Keyword :: NOT , Keyword :: NULL ] ) ?,
748+ ) ;
749+ AlterColumnAction :: SetNotNull { set_not_null_span }
750+ }
751+ _ => parser. expected_failure ( "'DEFAULT' or 'NOT NULL'" ) ?,
752+ }
753+ }
754+ Token :: Ident ( _, Keyword :: DROP ) => {
755+ let set_span = parser. consume ( ) ;
756+ match parser. token {
757+ Token :: Ident ( _, Keyword :: DEFAULT ) => {
758+ let drop_default_span = parser. consume ( ) . join_span ( & set_span) ;
759+ AlterColumnAction :: DropDefault {
760+ drop_default_span : drop_default_span,
761+ }
762+ }
763+ Token :: Ident ( _, Keyword :: NOT ) => {
764+ let drop_not_null_span = set_span. join_span (
765+ & parser. consume_keywords ( & [ Keyword :: NOT , Keyword :: NULL ] ) ?,
766+ ) ;
767+ AlterColumnAction :: DropNotNull { drop_not_null_span }
768+ }
769+ _ => parser. expected_failure ( "'DEFAULT' or 'NOT NULL'" ) ?,
770+ }
771+ }
772+ Token :: Ident ( _, Keyword :: TYPE ) => {
773+ let type_span = parser. consume ( ) ;
774+ let type_ = parse_data_type ( parser, false ) ?;
775+ AlterColumnAction :: Type { type_span, type_ }
776+ }
777+ _ => parser. expected_failure ( "alter column action" ) ?,
778+ } ;
779+ AlterSpecification :: AlterColumn {
780+ alter_column_span : span,
781+ column,
782+ alter_column_action,
783+ }
784+ }
636785 _ => parser. expected_failure ( "alter specification" ) ?,
637786 } ) ;
638787 if parser. skip_token ( Token :: Comma ) . is_none ( ) {
0 commit comments