Skip to content

Commit 37ff667

Browse files
authored
Merge pull request #23 from antialize/alter_impromentes
Add parsing of alter column in alter statements
2 parents 91a2b3b + e02d47a commit 37ff667

File tree

5 files changed

+157
-9
lines changed

5 files changed

+157
-9
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sql-parse"
3-
version = "0.21.0"
3+
version = "0.22.0"
44
edition = "2021"
55
authors = ["Jakob Truelsen <[email protected]>"]
66
keywords = [ "mysql", "postgresql", "sql", "lexer", "parser" ]

src/alter.rs

Lines changed: 154 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ use alloc::vec::Vec;
1313
// limitations under the License.
1414
use 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)]
137175
pub 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)]
563645
pub 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() {

src/issue.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ impl<'a, 'b> IssueHandle<'a, 'b> {
6868
}
6969
}
7070

71-
7271
#[derive(Debug)]
7372
pub struct Issues<'a> {
7473
pub src: &'a str,

src/with_query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<'a> Spanned for WithBlock<'a> {
4343
/// let mut stmts = parse_statements(sql, &mut issues, &options);
4444
///
4545
/// # assert!(issues.is_ok());
46-
/// #
46+
/// #
4747
/// let delete: WithQuery = match stmts.pop() {
4848
/// Some(Statement::WithQuery(d)) => d,
4949
/// _ => panic!("We should get a with statement")

0 commit comments

Comments
 (0)